私はさまざまな並列計算にMPI_Scatter / MPI_Gatherを使用してきました。私が気づいたことの1つは、OpenMPバリアディレクティブと同様に、プロセッサを同期するためにMPI_Barrier()が頻繁に呼び出されることです。プロジェクトのコードを微調整していて、以下のMPI_Barrier()行をコメントアウトしたところ、計算がまだ正しいことがわかりました。なぜそうなのですか?最初のMPI_Barrier()が必要な理由を理解できます。他のプロセッサは待つ必要がありません。プロセッサMASTERからデータを取得するとすぐに、計算を開始できます。しかし、MPI_Gatherの後にMPI_Barrierが必要になることはありますか、それともMPI_Gatherにはすでに暗黙のバリアがありますか?
編集:この場合、処理されるデータのサイズは重要ですか?
MPI_Scatter(&sendingbuffer,sendingcount,MPI_FLOAT,receivingbuffer,sendcount,
MPI_INT,MASTER_ID,MPI_COMM_WORLD);
// PERFORM SOME COMPUTATIONS
MPI_Barrier(); //<--- I understand why this is needed
MPI_Gather(localdata,sendcount, MPI_INT, global,sendcount, MPI_INT, MASTER_ID, MPI_COMM_WORLD);
//MPI_Barrier(); <------ is this ever needed?
障壁は必要ありません!
MPI_Gather
はブロッキング操作です。つまり、呼び出しが完了した後に出力を使用できます。非ルートランクは、ルート/他のランクが操作を開始する前に完了することが許可されていますが、完了する保証はないため、これは障壁を意味するものではありません。ただし、市内通話が完了した後、ランクにアクセスglobal
して任意のランクでMASTER_ID
再利用することは完全に安全localdata
です。
メッセージベースのMPIとの同期は、共有メモリのOpenMPとは異なります。通信をブロックする場合、通常、明示的な同期は必要ありません。呼び出しが完了した後、結果が利用可能であることが保証されます。
種類の同期は、非ブロッキング通信のために必要であるが、それを介して行われるMPI_Test
/MPI_Wait
特定のメッセージに-あなたが代用しようとした場合の障壁にも正しさの誤った感覚を提供するかもしれないMPI_Wait
とMPI_Barrier
。一方的なコミュニケーションでは、それはより複雑になり、障壁が役割を果たす可能性があります。
実際には、バリアが必要になることはめったにありません。代わりに、不要な同期を導入しないようにバリアを避けてください。
編集:矛盾する他の答えを考えると、ここに標準(MPI 3.1、セクション5.1)の引用(私の強調)があります。
集合通信への発信者の参加が終了するとすぐに、集合操作を完了することができます(必須ではありません)。呼び出しが戻るとすぐに、ブロック操作が完了します。非ブロッキング(即時)呼び出しには、個別の完了呼び出しが必要です(セクション3.7を参照)。集合操作の完了は、呼び出し元が通信バッファー内の場所を自由に変更できることを示します。グループ内の他のプロセスが操作を完了した、または開始したことを示すものではありません(操作の説明で特に暗示されていない限り)。したがって、集合的な通信操作は、すべての呼び出しプロセスを同期する効果がある場合とない場合があります。もちろん、このステートメントはバリア操作を除外します。
最近の編集に対処するには:いいえ、この場合、データサイズは正確性に影響を与えません。MPIのデータサイズは、誤ったMPIプログラムがデッドロックするかどうかに影響を与える場合があります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加