10

一見ばかげた質問ですが、どちらにしても決定的な答えを見つけることができないようです。

基本的な質問は、MPI::Isendに対応するMPI::Irecvが必要ですか?

つまり、メッセージの送信が非ブロッキングであっても、送信が完了するのを待ってから送信バッファーを再利用する限り、非ブロッキングの受信を使用して、送信されたバッファーを受信するのを待つ必要がありますか?

私のポイントは、メッセージの送信中に「他のことを行う」ために非ブロッキング送信を使用したいのですが、受信者プロセスはすぐにバッファーを使用するので、バッファーが実際に受信されるまでブロックしてもらいたいということです。

MPI :: Isendで送信されたにもかかわらず、MPI :: Recvでメッセージを受信できるはずですが、何かが足りないのではないかと思います。

簡単な擬似コード

  if( rank == 0 ){
   int r;
   for ( int i = 0; i < n; i++ ){

     // DO SOME STUFF HERE...

     request.Wait(status);
     request2.Wait(status);
     request3.Wait(status);

     r = i;
     memcpy( key, fromKey(i), ...);
     memcpy( trace, fromTrace(i), ...);

     request  = MPI::COMM_WORLD.Isend( &r, 1, MPI::INT, node, tag );
     request2 = MPI::COMM_WORLD.Isend( key, 10, MPI::INT, node, tag );
     request3 = MPI::COMM_WORLD.Isend( trace, nBytesTotal, MPI::BYTE, node, tag );

     // DO SOME MORE STUFF HERE.

   }
   r = -1;
   request  = MPI::COMM_WORLD.Isend( &r, 1, MPI::INT, node, tag );

   // Carry on ...

  } else {

   int r = -1;
   MPI::COMM_WORLD.Recv( &r, 1, MPI::INT, 0, tag, status );
   while( r >= 0 ){

     MPI::COMM_WORLD.Recv( &key, 10, MPI::INT, 0, tag, status );
     memcpy( saveKey, key, ...);

     MPI::COMM_WORLD.Recv( &trace, nBytesTotal, MPI::BYTE, 0, tag, status );
     memcpy( saveTrace, trace, ...);

     MPI::COMM_WORLD.Recv( &r, 1, MPI::INT, 0, tag, status );
  }
4

3 に答える 3

19

いいえ、通信の両端でブロッキングと非ブロッキングのMPI操作を自由に組み合わせることができます。ブロッキングは、MPI呼び出しが制御をコードに戻すタイミングに関連しており、送信されるメッセージのコンテンツには関連していません。

すべてのMPIメッセージには、送信元、宛先、タグ、およびコミュニケータを含む「エンベロープ」が含まれています。メッセージを正常に受信するには、受信操作がそのエンベロープとのみ一致する必要があります。エンベロープは、メッセージがどの程度正確に送信されたかを指定するものではありません。ブロッキングを介したものか、非ブロッキング操作を介したものか、同期送信(MPI_Ssend)またはバッファリングされた送信( MPI_Bsend)でした。唯一の例外は、一致する受信操作がすでに投稿されているか、メッセージが配信されないことで開始される、MPI_Rsend()またはそれを必要とする、いわゆる「準備完了モード」送信です。MPI_Irsend()

そのため、「マッチング受信操作」という用語は、「対応する受信機能」のようなものではなく、MPI標準全体で使用されています。

于 2012-05-18T16:54:41.460 に答える
2

はい、これで問題ありません。send / recvの「種類」(またはそれらを呼び出したいもの)が一致する必要はありません。

于 2012-05-18T16:39:58.753 に答える
0

これは、使用する送信/受信に関係ありません。しかし、実装は重要です。コード内のブロッキングポイントに注意する必要があります。たとえば、ブロッキング通信を使用する場合は、呼び出しの送受信に注意する必要があります。たとえば、このコードを見てください。

 if(rank==0)
 {
 MPI_Send(x to process 1)
 MPI_Recv(y from process 1)
 }
 if(rank==1)
 {
 MPI_Send(y to process 0);
 MPI_Recv(x from process 0);
 }

この場合はどうなりますか?プロセス0はxをプロセス1に送信し、プロセス1がxを受信するまでブロックし、プロセス0はyをプロセス0に送信し、プロセス0がyを受信するまでブロックしますが、プロセス0はブロックされるため、プロセス1は2つのプロセスを強制終了するまで無限にブロックします

于 2012-05-22T13:11:26.977 に答える