8

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

この後、34と34が得られます。私の質問は、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は最初に送信してから受信するのではなく、送信と受信を同時に実行します。

4

2 に答える 2

19

おっしゃるとおりMPI_Sendrecv、送信の後に受信が続くのは同じではありません。MPI_IsendMPI_Irecv、および のペアと考えてくださいMPI_Wait。したがって、実際には、送信と受信は並行して進行します。

ちなみに、これはMPIライブラリで一般的に実装されている方法です。

2 番目の例でデッドロックを修正したい場合、プロセスは送信と受信を別の順序で発行する必要があります。したがって、ランク 0 は送信の後に受信を発行し、ランク 1 - 受信の後に送信を発行します。

于 2012-06-13T17:28:22.410 に答える