1. ホーム
  2. synchronization

[解決済み】MPI_Barrier()を使用する必要があるのはどのような場合ですか?)

2022-02-06 17:28:59

質問

バリアはいつ使えばいいんだろう?例えば、散開/集合の前/後に必要なのでしょうか?それともOMPIは、すべてのプロセスがその時点に到達していることを確認してから散開/集合すべきなのでしょうか?同様に、ブロードキャストの後では、すべてのプロセスがすでにメッセージを受信していると考えていいのでしょうか?

どのように解決するのですか?

MPI-3.0以前のMPIの集団演算はすべてブロッキングです。つまり、その演算が返った後に渡されたバッファをすべて使用しても安全ということです。特に、これらの関数のいずれかが返ったときに、すべてのデータを受け取っていたことを意味します。(ただし、すべてのデータが送信されたことを意味するものではありません!) したがって、すべてのバッファがすでに有効であれば、MPI_Barrier は集団操作の前後には必要ありません(あるいはあまり役に立ちません)。

MPI_Barrier はノンブロッキングの呼び出しを魔法のように待ってくれるわけではないことにも注意してください。ノンブロッキングの send/recv を使用し、両方のプロセスが send/recv ペアの後に MPI_Barrier で待機する場合、MPI_Barrier の後にすべてのデータを送信/受信することは保証されません。代わりにMPI_Wait(とその仲間)を使用してください。そのため、以下のコードにはエラーが含まれています。

/* ERRORNOUS CODE */

Code for Process 0:
Process 0 sends something using MPI_Isend
MPI_Barrier(MPI_COMM_WORLD);
Process 0 uses buffer passed to MPI_Isend // (!)

Code for Process 1:
Process 1 recvs something using MPI_Irecv
MPI_Barrier(MPI_COMM_WORLD);
Process 1 uses buffer passed to MPI_Irecv // (!)

でマークされている行は、いずれも (!) は安全ではありません!

MPI_Barrier が役に立つのは、ほんの一握りの場合だけです。ほとんどの場合、プロセスが同期しているかどうか気にすることはありません。ブロッキングとノンブロッキングコールについてもっとよく読んでください!