MPI消息的“顺序”性
MPI要求消息是不可超越的(nonovertaking)。即如果q号进程发送了两条消息给r号进程,那么q进程发送的第一条消息必须在第二条消息之前可用。但是,如果消息是来自不同进程的,消息的到达顺序是没有限制的。即如果q号进程和t号进程都向r号进程发送了消息,即使q号进程在t号进程发送消息之前就将自己的消息发送出去了,也不要求q号进程的消息在t号进程的消息之前一定能被r号进程所访问。这本质上是因为 MPI不能对网络的性能有强制性要求。例如,如果q号进程在火星上的某台机器上运行,而r号进程和t号进程都在旧金山的同一台机器上运行,并且q号进程只是在t号进程发送消息之前的1纳秒发送了消息,那么要求q号进程的消息在t号进程之前到达,是不合理的。
也就是,对于0号进程给1号进程两条消息,这样对于第一条第二条是有顺序的。
但是对于0号和1号都给2号进程发一条消息,不能因为你0号消息早一点而要求2号进程必须接受先你0号的消息,而后接受1号的消息,这样是不合理的。就好比我从北京去长沙,他从武汉去长沙,只不过我先启动1分钟,而导致不能要求长沙先接收我而拒绝早到的他。
编写安全的MPI程序
死锁
进程0的第一条接收语句A能否完成取决于进程1的第二条发送语句D,即A依赖于D,从执行次序上可以明显地看出,进程0向进程1发送消息的语句C的执行又依赖于它前面的接收语句A的完成,即C依赖于A;同时,进程1的第一条接收语句B能否完成取决于进程0的第二条发送语句C的执行,即B依赖于C,从执行次序上可以明显地看出,向进程0发送消息的语句D的执行又依赖于B的完成,故有A依赖于D,而D又依赖于B,B依赖于C,C依赖于A,形成了一个环,进程0和进程1相互等待,彼此都无法执行下去,必然导致死锁。
不安全
由于进程0或进程1的发送需要系统提供缓冲区(在MPI的四种通信模式中有详细的解释),如果系统缓冲区不足,则进程0或进程1的发送将无法完成,相应的,进程1和进程0的接收也无法正确完成。显然对于需要相互交换数据的进程,直接将两个发送语句写在前面也是不安全的。
说明:当进程0发送的消息长度超过缓冲区大小时,要等到全部消息发送完成函数才能返回,在这种情况下,A的完成依赖于D的成功接收,而D的调用依赖于B的完成,B发送消息要等到C成功接收,而C的调用依赖于A的完成,从而造成彼此依赖,陷入死锁。
文章评论