目录
前面章节介绍的内容都是基于阻塞通信模式,本节我们学习另一种高级通信模式——非阻塞通信,其主要用于实现计算和通信的重叠。
一、阻塞通信
当一个阻塞通信正确返回后,结果为:1、该调用要求的通信操作已经正确完成,消息已经成功发出或接收。2、该调用的缓冲区可用,如果是发送操作,则该缓冲区可以被其它的操作更新;如果是接收操作,该缓冲区的数据已经完整,可被正确引用。
阻塞通信中,接收进程在接收消息时,除了要求接收到的消息的消息信封和接收操作自身的消息信封一致外,还要求接收到的消息是最早发送给自己的消息。若两个消息的消息信封都与自己的吻合,则必须先接收首先发送的消息,即使后发送的消息先到达,该接收操作也必须等待第一个消息。
下图中,进程0先后发送两条消息给进程1,进程1的第一个接收语句可以与任何一个发送语句的消息相匹配,但是根据有序接收的语义约束,由进程0发送的第一个消息必须被进程0的第一个接收语句接收,而由进程0发送的第二个消息必须被进程1的第二个接收语句接收。如果进程0的第一个消息先到达,进程1的第一条接收语句也不能接收它。
CALL MPI_COMM_RANK(comm, rank, ierr)
IF(rank .EQ. 0) THEN
CALL MPI_BSEND(buf1, count, MPI_REAL, 1, tag, comm, ierr)
CALL MPI_BSEND(buf2, count, MPI_REAL, 1, tag, comm, ierr)
ELSE IF(rank .EQ. 1) THEN
CALL MPI_RECV(buf1, count, MPI_REAL, 0, MPI_ANY_TAG, comm, status, ierr)
CALL MPI_RECV(buf2, count, MPI_REAL, 0, tag, comm, status, ierr)
ENDIF
二、非阻塞通信
MPI提供的非阻塞通信调用的函数十分丰富,所有阻塞通信的形式都有相应的非阻塞通信形式。由于通信经常需要较长的时间,在阻塞通信还没有结束的时候,处理单元只能等待,这样就会浪费了计算单元。一种常见的技术就是使计算与通信重叠,非阻塞通信可以实现这一目的。非阻塞通信主要用于计算和通信的重叠,从而提高整个程序执行的效率。此外,非阻塞通信还可以实现一些特殊的控制功能。
对于非阻塞通信,不必等到通信操作完全完成便可以返回,该通信操作可以交给特定的通信硬件去完成,在该通信硬件完成该通信操作的同时,计算单元可以同时进行计算操作,这样便实现了计算与通信的重叠。通过这样的方式,可以大幅提升程序执行效率,这一方法和通过异步I/O实现I/O与计算的重叠思路是完全一样的。
由于当非阻塞通信调用返回时一般该通信操作还没有完成,因此对应非阻塞的发送操作,发送缓冲区必须等到发送完成后才能释放,这样便需要引入新的手段(非阻塞通信完成对象)使程序员知道何时该消息已经成功发送。同样的,对于非阻塞的接收操作,该调用返回后并不意味着接收消息已经全部到达,必须等到消息到达后才可以引用接收到的消息数据。
从上面可看出,对于阻塞通信,只需要一个调用函数即可完成,但是对于非阻塞通信,一般需要两个调用函数,首先是非阻塞通信“启动”,但启动并不意味着该通信过程的完成,因此,为了保证通信的完成,还必须调用与该通信相联系的通信“完成”调用接口,通信完成调用才真正将非阻塞通信完成。
非阻塞通信和四种阻塞通信模式相结合,可以有四种不同的形式。针对某些通信是在一个循环中重复执行的情况,为了进一步提供优化的可能和提高效率,MPI又引入了重复非阻塞通信方式,对于重复非阻塞通信,和四种通信模式相结合,又有四种不同的形式。
各种非阻塞通信形式的效果都是将非阻塞通信的基本特征和具体的通信模式相结合后的总和体现,比如非阻塞缓存发送就是非阻塞+缓存的结果。
由于非阻塞通信返回并不意味着通信的完成,MPI还提供了各种非阻塞通信的完成方法和完成检测方法。MPI可以一次完成一个非阻塞通信,也可以一次完成所有的非阻塞通信,还可以一次完成任意一个或多个非阻塞调用,对于非阻塞通信是否完成的检测也有以上各种形式。
通信模式 | 发送 | 接收 | |
标准通信模式 | MPI_ISEND | MPI_IRECV | |
缓存通信模式 | MPI_IBSEND | ||
同步通信模式 | MPI_ISSEND | ||
就绪通信模式 | MPI_IRSEND | ||
重复非阻塞通信 | 标准通信模式 | MPI_SEND_INIT | MPI_RECV_INIT |
缓存通信模式 | MPI_BSEND_INIT | ||
同步通信模式 | MPI_SSEND_INIT | ||
就绪通信模式 | MPI_RSEND_INIT |
非阻塞通信的数量 | 检测 | 完成 |
一个非阻塞通信 | MPI_TEST | MPI_WAIT |
任意一个非阻塞通信 | MPI_TESTANY | MPI_WAITANY |
一到多个非阻塞通信 | MPI_TESTSOME | MPI_WAITSOME |
所有非阻塞通信 | MPI_TESTALL | MPI_WAITALL |
虽然发送和接收操作的类型很多,但只需要消息信封相吻合,并且符合有序接收的语义约束,任何形式的发送和任何形式的接收都可以相匹配。