私はMPIを初めて使いました。私は4つのプロセスを持っています:プロセス1から3はベクトルを生成してプロセス0に送り、プロセス0はベクトルを1つの非常に長いベクトルにまとめます。私は動作するコードがありますが(投稿するには時間がかかります)、プロセス0のrecv操作は不器用で非常に遅いです。抽象的でMPIがルートプロセスでアレイを集める
、コードは以下のない:
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
(0.7秒を完了するためのプログラムのための1.5秒と比較して)ことが分かります。
プロセス1からのベクターを受信し、プロセス0のall_arrays
に保存する方が良いでしょうか?
私はMPI :: Comm :: Gatherをチェックアウトしましたが、使い方がわかりません。特に、プロセス1の配列がall_arraysの最初の配列、プロセス2の配列が2番目の配列などであることを指定できますか?ありがとう。
編集
:は、私が「遅い」ループを削除し、代わりの間で次のように置くブロック「場合」:MPI_Gather(my_array,n*m,MPI_DOUBLE,
&all_arrays[(id-1)*m*n],n*m,MPI_DOUBLE,0,MPI_COMM_WORLD);
同じパフォーマンスの低下が生じました。これは、ルートプロセスが個々の受信が完了するのを「待機」してから次の受信を試みるという事実と関係していますか?それともそれについて考えるのは正しい方法ではありませんか?
簡単なコメント - C++バインディングは現在のMPI標準バージョン2.2では廃止され、今後のMPI 3.0では完全に削除される予定です。移植性の理由から、代わりにCインターフェイスを学習して使用することをお勧めします。 –
あなたのプログラムには 'n'と' m'の大きさがあり、あなたのマシンにはどんな種類の接続がありますか? – suszterpatt
Hristo、ありがとう - 私は自分のコードをCのインターフェイスに変更しました。 – covstat