我还不熟悉MPI。我有4个进程:1到3进程填充一个向量并将其发送到进程0,进程0将这些向量收集成一个非常长的向量。我有能够运行的代码(太长无法发布),但是进程0的接收操作很笨拙而且非常慢。
简单来说,该代码执行以下操作:
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%(相较于完成程序需要1.5秒而言,占用了0.7秒)。
有没有更好的方法从进程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);
出现了相同的缓慢表现。这是否与根进程在尝试下一个接收之前“等待”每个单独接收完成有关?还是说这种想法是错误的?
n
和m
的规模有多大?你的机器之间有什么样的连接关系? - suszterpatt