私はMPIが初めてです。私は 4 つのプロセスを持っています: プロセス 1 から 3 はベクトルを設定してプロセス 0 に送信し、プロセス 0 はベクトルを 1 つの非常に長いベクトルに収集します。機能するコード (投稿するには長すぎる) がありますが、プロセス 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();
合計時間の 50%を占めていることがendcomm - startcomm
わかります (プログラムが完了するのに 1.5 秒かかるのに対し、0.7 秒)。
プロセス 1 ~ 3 からベクトルを受け取り、プロセス 0 に保存するより良い方法はありall_arrays
ますか?
MPI::Comm::Gather を調べましたが、使い方がわかりません。特に、プロセス 1 の配列を all_arrays の最初の配列、プロセス 2 の配列を 2 番目の配列などに指定できますか? ありがとう。
編集:「遅い」ループを削除し、代わりに「if」ブロックの間に次を配置しました。
MPI_Gather(my_array,n*m,MPI_DOUBLE,
&all_arrays[(id-1)*m*n],n*m,MPI_DOUBLE,0,MPI_COMM_WORLD);
同じ遅いパフォーマンスが発生しました。これは、ルート プロセスが個々の受信が完了するのを「待機」してから、次の受信を試行するという事実と関係がありますか? それとも、それについて考えるのは正しい方法ではありませんか?