MPI-Avoid deadlock

MPI程序在周期性拓扑中可能会遇到死锁问题,当进程使用blocking模式进行数据通信时,可能导致循环依赖。解决方法包括改变send和receive的顺序,使用non-blocking通讯,或利用MPI_Sendrecv。正确的同步策略可以防止死锁,确保并行程序的正常运行。
摘要由CSDN通过智能技术生成

MPI-DEADLOCK ISSUE!
设进程i向i+1发送数据(循环进行,周期性拓扑)。进行i可以用标准模式向右边近邻发送数据,然后用blocking模式接收左边近邻的数据。

MPI_Comm_size(comm,&size);
MPI_Comm_rank(comm,&rank);
rightrank = (rank+1)%size;
leftrank = (rank+size-1)%size;

MPI_Send(buf1,count,MPI_INT,rightrank,tag,comm);
MPI_Recv(buf2,count,MPI_INT,leftrank,tag,comm,&status);

对每一个进程而言,接收操作在发送操作没有完成之前不能执行。但发送操作是否完成,和接收操作有关,因此,上面的代码有循环依赖问题。由于使用标准模式的发送,send操作可能block,直到有一个匹配的接收操作出现。
以上代码只有在系统有充分大的buffer的时候才能工作,此时,send操作由于数据被拷贝的buffer中因此能返回,因此,匹配的receive操作能够执行。如果没有足够的buffer,MPI未指定输出,但对很多MPI的实现来说,将造成deadlock. 即MPI_Send永远不会返回,每一个进程都在等待下一个进程执行相应的receive操作。因此上面的代码在不同系统上有不同的行为,在同一个系统上,依据消息的尺寸,行为也会不同。
有以下几个方法来避免以上问题:
第一:在不同进程上,颠倒send和receive的次序(至少两个进程才能正确工作)

if(rank%2){
MPI_Recv(buf2,count,MPI_INT,leftrank,tag,comm,&status);
MPI_Send(buf1,count,MPI_INT,rightrank,tag,comm);
else{
MPI_Send(buf1,count,MPI_INT,rightrank,tag,comm);
MPI_Recv(buf2,count,MPI_INT,leftrank,tag,comm);

设有3个进程,首先0号准备接收来自2号的消息,2号准备接收来自1号的消息,而1号首先发送消息给2号,2号已经准备接收,所以1号的发送能够正确返回,然后2号的接收能正确返回,然后2号发送到0号执行,0号接收能够正确执行,然后0号发送1号开始,1号现在能够接收,正确返回。因此上述代码消除了deadlock.

第二个方法是利用non-blocking 通讯。可以使用non-blocking 的send或receive或者两个都用non-blocking模式。其区别在于,如果一个使用non-blocking的send,MPI_Isend能够开始一个send操作并且立即返回,然后后面的receive能够执行,从而使得整个通讯过程能够顺利完成。应注意的是,在调用MPI_Isend之后,在buf1中的data不能被立即修改,直到确保数据已经被发送或拷贝到系统缓存之中。MPI 提供MPI_Wait和MPI_Test来检查这些状态:

MPI_Isend(buf1,count,MPI_INT,rightrank,tag,comm,&request);
MPI_Recv(buf2,count,MPI_INT,leftrank,tag,comm,&status);
MPI_Wait(&request,&status);

还可以先执行non-blocking的receive:

MPI_Irecv(buf2,count,MPI_INT,leftrank,tag,comm,&request);
MPI_send(buf1,count,MPI_INT,rightrank,tag,comm);
MPI_Wait(&request,&status);

MPI_Irecv将首先post一个receive,然后执行后面的blocking send操作。MPI_Irecv暗示MPI收到的数据应该存在buf2中,MPI_Wait用来阻塞程序,直到输入数据实质上被接收进了buf2.这个模式通常导致更快的速度,因为在很多MPI实现上,当一个匹配的receive已经被post的时候,send操作完成的特别快(不需要握手信号)。
当然,也可以用MPI_Sendrecv解决问题:

MPI_Sendrecv(buf1,count,MPI_INT,rightrank,tag,
             buf2,count,MPI_INT,leftrank,tag,comm,&status);
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值