学习笔记-MPI的四种通信模式
MPI共有四种通信模式。主要根据以下不同的情况来区分:
- 是否需要对发送的数据进行缓存?
- 是否只有当接收调用执行后才可以执行发送操作?
- 什么时候发送调用可以正确返回?
- 发送调用正确返回是否意味着已经发送完成?(发送缓冲区是否已经可用?/数据是否已经到达接收缓冲区?)
标准通信模式
MPI自身决定是否对发送数据进行缓存。
若缓存发送数据,则发送调用的正确返回不依赖于接收进行。
若不缓存发送数据,直接发送数据,则只有当相应的接收调用执行且数据完全到达接收缓冲区后,发送调用才正确返回。
阻塞与非阻塞
非阻塞通信在第12章被介绍,各种分类容易造成混淆,在此略微提及。
阻塞通信指发送方的send操作必须有接收方的recv操作才能完成。
阻塞通信的正确返回意味着:
- (发送/接收)调用已经正确返回。
- 缓冲区已经可用(发送缓冲区可被重用/接收缓冲区数据已经完整)。
非阻塞通信
对于非阻塞通信,不必等到通信操作完全完成就可以返回。通信操作交给特定的通信硬件完成,实现了计算与通信重叠。并引入非阻塞通信完成对象指明通信操作已经完成。
在阻塞通信中存在四种通信模式,对应的,在非阻塞通信中也有四种通信模式。
缓存通信模式
由用户直接对通信缓冲区进行申请、使用和释放。调用接口为MPI_BSEND(),参数与MPI_SEND完全相同。
不依赖于接收调用是否已经启动,只要用户保证有发送缓冲区可用,发送调用都可以正确返回。(在阻塞发送时,发送调用正确返回后可以直接对发送缓冲区进行重用,在非阻塞发送时,正确返回并不意味着发送缓冲区可以被重用。)
用户可以首先申请缓冲区并提交给MPI作为发送缓存,从而支持缓存通信模式。在不使用时可以暂时释放。
double buffer[SIZE],*tmpbuffe,*tmpbuf;
void Buffered_Test_Send(buffer,buffer_size){}
//......
//......
tmpbuffer=(double&)malloc(size)//申请所需要的空间
MPI_Buffer_attach(tmpbuffer,size);//申请到的空间递交给MPI
Buffered_Test_Send(buffer,SIZE);//执行缓存消息发送
MPI_Buffer_detach(&tmpbuf,&tsize);//回收发送缓存区
//......
缓存通信模式是刻意要求的有缓存的标准通信模式,在保证了缓冲区后,发送调用可以立即完成。
同步通信模式
****同步发送调用的正确返回意味着发送缓冲区已经被系统缓冲区缓冲完毕且接受进程已经开始接收。
同步消息发送的正确返回依赖于接收进程的开始,且正确返回后缓冲区已经可以重用,属于阻塞通信。
调用接口为MPI_Ssend(),参数与MPI_Send()相同。
就绪通信模式
只有当接收进程的接受操作已经启动时,才可以在发送进程启动发送操作。
为了实现就绪通信模式,可以在接收进程的接收调用之后以及发送进程的发送调用之前添加一个阻塞的发送接收过程。保证接收进程的接收调用早于发送进程的发送调用。
启动发送操作后,可以进行阻塞的发送调用,也可以进行非阻塞的发送调用。对于非阻塞发送的正确返回并不意味着发送已经完成,对于阻塞发送的正确返回,则可以重用发送缓冲区。
if(rank==dest)//接收进程
{
MPI_Irecv(buf,size,MPI_XX,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD);//执行一个非阻塞的接收调用,立刻正确返回
MPI_Send(buffer,size,MPI_XX,source,tag,MPI_COMM_WORLD);//向发送进程发送一个阻塞的发送调用。
}
else:
//发送进程
MPI_Recv(buffer,size,MPI_XX,dest,MPI_ANY_TAG,MPI_COMM_WORLD);//放在就绪发送调用之前,确保接受进程的接受调用启动后,再进行就绪发送。
MPI_Rsend(buf,size,MPI_XX,dest,tag,MPI_COMM_WORLD,ieer);//接收进程的阻塞发送结束后再开始执行。
小结
标准通信模式之外的的其他通信模式,是MPI提供给程序员附加的并行程序通信手段,它是当程序员认为标准通信模式不能满足要求或者不能很好地满足给定的要求时所采取的措施,它要求程序员对程序和通信过程有更准确更深刻的理解,在此基础上,根据不同的需要,使用不同的通信模式,往往可以达到优化和提高效率的目的。