MPI_SENDRECV是如何工作的?
我有一个关于MPI_SENDRECV的问题。 以下是一个例子:MPI_SENDRECV是如何工作的?,mpi,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_C
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
在这之后,我们得到了34和34。
我的问题是我们要替换MPI_SENDRECV(如果我们假设MPI_SENDRECV先发送,然后接收)
那么这就是僵局
这意味着MPI_SENDRECV不是先发送然后接收,而是同时发送ans接收,对吗?你说得对,
MPI_SENDRECV
与先发送后接收不同。可以将其视为一个MPI-Isend
,MPI-Irecv
,以及一对MPI-Wait
s。因此,实际上,发送和接收是并行进行的
顺便说一句,这就是它在MPI库中通常的实现方式
如果您想修复第二个示例中的死锁,那么进程必须以不同的顺序发出发送和接收。因此,秩0将发出一个发送,然后是接收,秩1-一个接收,然后是发送
即使消息被路由到接收进程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
非常感谢,我现在知道了!MPI_Sendrecv_replace()如何工作?它是否使用阻塞发送和接收?MPI_Sendrecv_replace可能需要一个单独的问题(这是一个新添加的操作)。我可以想象有两种不同的实现(我相信致力于优化MPI的研究小组会将这些实现相互比较)。OpenMPI使用的实现将要发送的数据复制到临时缓冲区中,然后调用常规的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,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