我是 MPI 的新手。我有 4 个进程:进程 1 到 3 填充一个向量并将其发送到进程 0,进程 0 将向量收集到一个非常长的向量中。我有有效的代码(太长无法发布),但是进程 0 的 recv 操作很笨拙而且很慢。
抽象地说,代码执行以下操作:
MPI::Init();
int id = MPI::COMM_WORLD.Get_rank();
if(id>0) {
double* my_array = new double[n*m]; //n,m are int
Populate(my_array, id);
MPI::COMM_WORLD.Send(my_array,n*m,MPI::DOUBLE,0,50);
}
if(id==0) {
double* all_arrays = new double[3*n*m];
/* Slow Code Starts Here */
double startcomm = MPI::Wtime();
for (int i=1; i<=3; i++) {
MPI::COMM_WORLD.Recv(&all_arrays[(i-1)*m*n],n*m,MPI::DOUBLE,i,50);
}
double endcomm = MPI::Wtime();
//Process 0 has more operations...
}
MPI::Finalize();
事实证明,endcomm - startcomm
这占总时间的 50%(0.7 秒,而程序完成需要 1.5 秒)。
有没有更好的方法来接收来自进程 1-3 的向量并将它们存储在进程 0 中all_arrays
?
我检查了 MPI::Comm::Gather,但我不确定如何使用它。特别是,它是否允许我指定进程 1 的数组是 all_arrays 中的第一个数组,进程 2 的数组是第二个,等等?谢谢。
编辑:我删除了“慢”循环,而是将以下内容放在“if”块之间:
MPI_Gather(my_array,n*m,MPI_DOUBLE,
&all_arrays[(id-1)*m*n],n*m,MPI_DOUBLE,0,MPI_COMM_WORLD);
结果同样缓慢。这是否与根进程在尝试下一个接收之前“等待”每个接收完成的事实有关?或者这不是正确的思考方式?