这似乎是一个愚蠢的问题,但我似乎找不到明确的答案。
基本问题是,对于MPI::Isend是否需要对应MPI::Irecv?
也就是说,即使消息发送是非阻塞的,只要在重复使用发送缓冲区之前等待发送完成,我是否需要使用非阻塞接收和等待来接收已发送的缓冲区?
我的意思是,我想使用非阻塞发送来“做其他事情”,而消息正在发送中,但接收进程将立即使用缓冲区,因此我希望它们会阻塞,直到缓冲区真正被接收。
似乎我可以使用MPI :: Recv接收使用MPI :: Isend发送的消息,但我想知道是否有什么我错过了?
一些简单的伪代码:
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 );
}