一个看似愚蠢的问题,但我似乎无法以某种方式找到明确的答案.
基本问题是我需要为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,tag );
- request3 = MPI::COMM_WORLD.Isend( trace,nBytesTotal,MPI::BYTE,tag );
- // DO SOME MORE STUFF HERE.
- }
- r = -1;
- request = MPI::COMM_WORLD.Isend( &r,tag );
- // Carry on ...
- } else {
- int r = -1;
- MPI::COMM_WORLD.Recv( &r,tag,status );
- while( r >= 0 ){
- MPI::COMM_WORLD.Recv( &key,status );
- memcpy( saveKey,key,...);
- MPI::COMM_WORLD.Recv( &trace,status );
- memcpy( saveTrace,trace,...);
- MPI::COMM_WORLD.Recv( &r,status );
- }
解决方法
不,您可以在通信的两端自由混合阻塞和非阻塞MPI操作.阻止与MPI调用何时将控制权返回给您的代码而不是传输的消息内容有关.
每条MPI消息都带有一个“信封”,其中包含其源,目的地,标签和通信器.要成功接收消息,您的接收操作应仅与其信封匹配.信封绝不指定消息的确切发送方式 – 是通过阻塞,是通过非阻塞操作,是同步发送(MPI_Ssend)还是缓冲(MPI_Bsend).唯一的例外是所谓的“就绪模式”发送,它使用MPI_Rsend()或MPI_Irsend()启动,这要求匹配的接收操作已经发布或消息不会被传递.
这就是为什么术语“匹配接收操作”在整个MPI标准中使用而不是像“相应的接收功能”那样.