OpenMP与MPI混合做方阵向量乘法


按行分配

1 #include<stdio.h> 2 #include<mpi.h> 3 #include<stdlib.h> 4 #include<p.h> 5 6 #define N 100 7 8 //time_t start,end;//开始和结束时间 9 double start,end; 10 11 int main(int argc,char* argv[]) 12 36 37 //本进程处理的行数就是总阶数/进程数 38 my_row=N/cm_sz; 39 40 //为每个进程都申请空间 41 mat=malloc(N*my_row*sizeof(double)); //my_row行的小矩阵 42 vec=malloc(N*sizeof(int)); //每个进程各自读入列向量 43 result=malloc(my_row*sizeof(double));//每个进程各自的结果向量 44 45 //赋值(省去读入的步骤,实际做时是读入自己那部分) 46 //因为parallel for指令对外层j块选,故对vec[j]的操作无冲突 47 //此外,mat[]的每个元素只被一个线程操作一次,无冲突 48 # pragma p parallel for num_threads(thrdCnt) private(i) 49 for(j=0;j<N;j++) 54 55 //计算:j=0时做的是赋值 56 //因为parallel for指令对外层i块选,故对result[i]的操作无冲突 57 # pragma p parallel for num_threads(thrdCnt) private(j) 58 for(i=0;i<my_row;i++) 65 66 //聚集给0号进程 67 if(my_rank==0) 68 85 else 86 100 101 //0号进程负责输出 102 if(my_rank==0) 103 115 116 MPI_Finalize(); 117 /**********************/ 118 119 //最终,free应无遗漏 120 free(all_rst); 121 free(mat); 122 free(vec); 123 free(result); 124 125 return 0; 126 }

输出

1 [root@hostlzh mpi_p]# mpicc fopenmp o roo roc 2 [root@hostlzh mpi_p]# mpiexec n 4 ./roo 7 3 time=7.662773e03 4 The Result is: 5 4950.000000 6 4950.000000 7 4950.000000 8 4950.000000 9 4950.000000 10 4950.000000 11 4950.000000 12 4950.000000 13 4950.000000 14 4950.000000 15 4950.000000 16 4950.000000 17 [root@hostlzh mpi_p]#

按列分配

1 #include<stdio.h> 2 #include<mpi.h> 3 #include<stdlib.h> 4 #include<p.h> 5 6 #define N 100 7 8 //time_t start,end;//开始和结束时间 9 double start,end; 10 11 int main(int argc,char* argv[]) 12 36 37 //本进程处理的列数就是总阶数/进程数 38 my_col=N/cm_sz; 39 40 //为每个进程都申请空间 41 mat=malloc(my_col*N*sizeof(double)); //my_col列的小矩阵 42 vec=malloc(my_col*sizeof(int)); //每个进程各自读入一段列向量 43 result=malloc(N*sizeof(double));//每个进程各自的结果向量 44 45 //赋值(省去读入的步骤,实际做时是读入自己那部分) 46 //因为parallel for指令对外层i块选,故对vec[i]的操作无冲突 47 //此外,mat[]的每个元素只被一个线程操作一次,无冲突 48 # pragma p parallel for num_threads(thrdCnt) private(j) 49 for(i=0;i<my_col;i++) 54 55 //计算 56 //因为parallel for指令对外层i块选,故对result[i]的操作无冲突 57 # pragma p parallel for num_threads(thrdCnt) private(j) 58 for(i=0;i<N;i++) 64 65 //归约给0号进程 66 if(my_rank==0) 67 92 else 93 106 107 //0号进程负责输出 108 if(my_rank==0) 109 121 122 MPI_Finalize(); 123 /**********************/ 124 125 //最终,free应无遗漏 126 free(all_rst); 127 free(mat); 128 free(vec); 129 free(result); 130 131 return 0; 132 }

输出

1 [root@hostlzh mpi_p]# mpicc fopenmp o col.o col 2 [root@hostlzh mpi_p]# mpiexec n 10 ./col.o 3 3 time=4.535699e02 4 The Result is: 5 4950.000000 6 4950.000000 7 4950.000000 8 4950.000000 9 4950.000000 10 4950.000000 11 4950.000000 12 4950.000000 13 4950.000000 14 4950.000000 15 4950.000000 16 4950.000000 17 [root@hostlzh mpi_p]#

按块分配

1 #include<stdio.h> 2 #include<mpi.h> 3 #include<stdlib.h> 4 #include<p.h> 5 6 #define N 100 7 8 //time_t start,end;//开始和结束时间 9 double start,end; 10 11 //自己的求平方根的函数,因为math里的sqrt报错 12 int mysqrt(int k) 13 21 22 int main(int argc,char* argv[]) 23 48 49 t=mysqrt(cm_sz);//一行(列)有多少个子阵块 50 if(t==1) 51 56 //本进程处理的块阶数=总阶数/sqrt(进程数) 57 my_N=N/t; 58 59 //为每个进程都申请空间 60 mat=malloc(my_N*my_N*sizeof(double)); //my_N阶的小方阵 61 vec=malloc(my_N*sizeof(int)); //每个进程各自读入自己需要的那段列向量 62 result=malloc(my_N*sizeof(double));//每个进程各自的结果向量 64 //赋值(省去读入的步骤,实际做时是读入自己那部分) 65 //因为parallel for指令对外层i块选,故对vec[i]的操作无冲突 66 //此外,mat[]的每个元素只被一个线程操作一次,无冲突 67 # pragma p parallel for num_threads(thrdCnt) private(j) 68 for(i=0;i<my_N;i++) 73 74 //计算 75 //因为parallel for指令对外层i块选,故对result[i]的操作无冲突 76 # pragma p parallel for num_threads(thrdCnt) private(j) 77 for(i=0;i<my_N;i++) 83 84 /*聚集到0号进程上 85 实际上是开了cm_sz个my_N长度组成的总向量作聚集*/ 86 if(my_rank==0) 87 101 else 102 //聚集 103 MPI_Gather(result, 104 my_N, 105 MPI_DOUBLE, 106 all_rst, 107 my_N, 108 MPI_DOUBLE, 109 0, 110 MPI_CM_WORLD 111 ); 112 113 /*从结果长向量中计算结果 114 把后面的分量加到0~my_N1分量上去*/ 115 if(my_rank==0) 116 129 } 130 } 131 132 //补到前面 133 //和前面同样的原因,对all_rst数组不需保护 134 # pragma p parallel for num_threads(thrdCnt) private(k) 135 for(i=1;i<t;i++) 136 141 } 142 143 //计时结束 144 //end=time(NULL); 145 end=MPI_Wtime(); 146 //计算时间 147 //printf("time=%f\n",difftime(end,start)); 148 printf("time=%e\n",endstart); 149 printf("The Result is:\n"); 150 //改变跨度可以采样获取结果,快速结束I/O 151 for(i=0;i<N;i+=N/11) 152 printf("%f\n",all_rst[i]); 153 154 } 155 156 MPI_Finalize(); 157 /**********************/ 158 159 //最终,free应无遗漏 160 free(all_rst); 161 free(mat); 162 free(vec); 1 free(result); 164 165 return 0; 166 }

输出

1 [root@hostlzh mpi_p]# mpicc fopenmp o block.o block 2 [root@hostlzh mpi_p]# mpiexec n 4 ./block.o 5 3 time=2.295089e02 4 The Result is: 5 4950.000000 6 4950.000000 7 4950.000000 8 4950.000000 9 4950.000000 10 4950.000000 11 4950.000000 12 4950.000000 13 4950.000000 14 4950.000000 15 4950.000000 16 4950.000000 17 [root@hostlzh mpi_p]#



上一篇:Qt QTimer::singleShot问题及用法

下一篇:Breakpad(跨平台crash工具)


OpenMP
Copyright © 2002-2019 k262电脑网 www.k262.cn 皖ICP备2020016292号
温馨提示:部分文章图片数据来源与网络,仅供参考!版权归原作者所有,如有侵权请联系删除!QQ:251442993 热门搜索 网站地图