Cannon矩阵乘法的MPI实现及性能分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include
#include
#include
#include
#include
#include
MPI_Status status;
double **A, **B, **C; //C=A*B
double *a,*b,*c; //各个进程的缓冲区
int n; //矩阵的行列数
int np; //每个进程控制的小矩阵的行列数
int p,rank; //进程个个数、当前进程的编号,笛卡尔进程编号double *tempa, *tempb;
void ProduceABC(); //在根处理器中生成矩阵AB,初始化矩阵C void PrintABC();//输出结果
void ScatterAB();// 分发矩阵AB中的元素到各个进程中
void MainProcess(); //cannon算法的主过程
void collectC(); //收集结果矩阵C
void Mutiply(); //矩阵相乘
void Printab();
void Printc();
int main(int argc, char *argv[])
{
int i;
double starttime,endtime;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if(rank == 0)
{
printf("请输入矩阵的行列数n= ");
fflush(stdout);
scanf_s("%d", &n);
printf("\n");
}
MPI_Bcast(&n, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
// n = atoi(argv[1]);
np = n/(int)sqrt(p);
a = (double*)malloc(np*np*sizeof(double));
b = (double*)malloc(np*np*sizeof(double));
c = (double*)malloc(np*np*sizeof(double));
memset(c, 0, np*np*sizeof(double));
tempa = (double*)malloc(np*np*sizeof(double));
tempb = (double*)malloc(np*np*sizeof(double));
if(rank == 0)
{
//在根处理器中为矩阵ABC分配空间
A = (double**)malloc(n*sizeof(double*));
B = (double**)malloc(n*sizeof(double*));
C = (double**)malloc(n*sizeof(double*));
for(i = 0; i < n; i++)
{
A[i] = (double*)malloc(n*sizeof(double));
B[i] = (double*)malloc(n*sizeof(double));
C[i] = (double*)malloc(n*sizeof(double));
}
ProduceABC(); //在根处理器中随机生成矩阵AB,初始化矩阵C ScatterAB();// 分发矩阵AB中的元素到各个进程中
}
else
{
MPI_Recv(a, np*np, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD, &status);
MPI_Recv(b, np*np, MPI_DOUBLE, 0, 2, MPI_COMM_WORLD, &status); }
starttime=MPI_Wtime(); //开始时间
MainProcess(); //cannon算法的主过程
if(rank == 0)
{
collectC(); //收集结果矩阵C
PrintABC(); //输出结果
endtime=MPI_Wtime();
printf("time used: %lf\n",endtime - starttime);
for(i = 0; i < n; i++)
{
free(A[i]);
free(B[i]);
free(C[i]);
}
free(A);
free(B);
free(C);
}
else
{
MPI_Send(c, np*np, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD);
}
free(a);
free(b);
free(c);
free(tempa);
free(tempb);
MPI_Finalize();
return 0;
}
void ProduceABC()//在根处理器中生成矩阵AB
{
int i,j;
for(i=0; i for(j=0; j { A[i][j]=1.0; B[i][j]=1.0; C[i][j]=0.0; } } void PrintABC()//输出结果 { printf("A[0][0]=%f\nB[0][0]=%f\nC[0][0]=%f\n",A[0][0],B[0][0],C[0][0]); } void ScatterAB()// 分发矩阵AB中的元素到各个进程中 { int imin,imax,jmin,jmax; int sp; int i,j,k,m; for(k=0; k { /*计算相应处理器所分得的矩阵块在总矩阵中的坐标范围*/ sp = (int)sqrt(p); imin = (k / sp) * np;