MPI_SENDRECV如何工作?

时间:2012-06-13 15:23:16

标签: mpi

我对MPI_SENDRECV有疑问。 这是一个例子:

 PROGRAM sendrecv
  IMPLICIT NONE
  INCLUDE "mpif.h"
  INTEGER a,b,myrank,nprocs,ierr
  integer istat(MPI_STATUS_SIZE)
  CALL MPI_INIT(ierr)
  CALL MPI_COMM_SIZE(MPI_COMM_WORLD, nprocs, ierr)
  CALL MPI_COMM_RANK(MPI_COMM_WORLD, myrank, ierr)
  if (myrank.eq.0) then
     a=1;b=3
  else
     a=2;b=4
  endif

  if (myrank == 0) then
     call MPI_SENDRECV(b,1,MPI_REAL,1,0,
 .                     a,1,MPI_REAL,1,0,
 .                     MPI_COMM_WORLD,istat,ierr)
  elseif (myrank == 1) then
     call MPI_SENDRECV(b,1,MPI_REAL,0,0,
 .                     a,1,MPI_REAL,0,0,
 .                     MPI_COMM_WORLD,istat,ierr)
  end if
  if (myrank.eq.0) then
     write(*,*) b,a
  else
     write(*,*) a,b
  endif
  CALL MPI_FINALIZE(ierr)
  END

在此之后我们得到3 4和3 4。 我的问题是我们是替换MPI_SENDRECV(如果我们假设首先发送MPI_SENDRECV然后接收)

if (myrank == 0) then
   call MPI_SEND(b,1,MPI_REAL,1,0,MPI_COMM_WORLD,ierr)
   call MPI_RECV(a,1,MPI_REAL,0,0,MPI_COMM_WORLD,istat,ierr)                  
elseif (myrank == 1) then
   call MPI_SEND(b,1,MPI_REAL,0,0,MPI_COMM_WORLD,ierr)
   call MPI_RECV(a,1,MPI_REAL,1,0,MPI_COMM_WORLD,istat,ierr)                      
end if

然后这将是僵局 所以这意味着MPI_SENDRECV它不先发送然后接收,而是同时发送ans接收,对吗?

2 个答案:

答案 0 :(得分:15)

你是对的,MPI_Sendrecv与发送后跟接收不一样。可以将其视为MPI_IsendMPI_Irecv和一对MPI_Wait。所以实际上,发送和接收是并行进行的。

顺便说一下,这是它在MPI库中的常用方法。

如果您想在第二个示例中修复死锁,则进程必须以不同的顺序发出发送和接收。因此,排名0将发出一个发送,然后是接收,排名为1 - 接收后发送。

答案 1 :(得分:0)

  

即使消息被路由到接收进程B,进程B仍然必须确认它想要接收A的数据。一旦这样做,数据就会被传输。进程A被确认已传输数据并可能恢复工作。

所以你的第二个代码不能满足条件,这似乎是你没有接听别人的电话。它应该如下:

if (myrank == 0) then
   call MPI_SEND(b,1,MPI_REAL,1,0,MPI_COMM_WORLD,ierr)
   call MPI_RECV(a,1,MPI_REAL,1,0,MPI_COMM_WORLD,istat,ierr)
elseif (myrank == 1) then
   call MPI_SEND(b,1,MPI_REAL,0,0,MPI_COMM_WORLD,ierr)
   call MPI_RECV(a,1,MPI_REAL,0,0,MPI_COMM_WORLD,istat,ierr)
end if