考虑以下几点:Fortran语言/ MPI非阻塞发送
subroutine send_to_friend(a,b,c,request)
implicit none
include 'mpif.h' !use mpi if you've built the mpif90 bindings...
real a,b,c
real buff(3)
integer tag,dest,ierr,request
tag = 50
dest = 0
buff(1) = a
buff(2) = b
buff(3) = c
call MPI_Isend(buff,3,MPI_REAL,dest,tag,MPI_COMM_WORLD,request,ierr)
return
end subroutine send_to_friend
这可能会不起作用,因为buff
会在堆栈上(反正大多数现代编译)放,但将当子程序退出时擦干净。分配数组也没有帮助,因为根据here(第10节),当您退出过程时分配的数组会自动解除分配 - 在C中,这将是内存泄漏(也是不好的)。什么是这样做的正确方法?我应该用save
属性声明该数组吗? (C中的static
)。这种设计本身是否有缺陷?
是的,我很想说设计本身就存在问题;即使使用'save',如果连续快速调用这个子程序两次会发生什么?您可以使用['MPI_Bsend'](http://www.mcs.anl.gov/research/projects/mpi/www/www/MPI_Bsend.html)和“足够的”用户定义缓冲区空间,并管理缓冲区MPI的问题,但[缓冲发送是邪恶的](http://blogs.cisco.com/performance/top-10-reasons-why-buffered-sends-are-evil/) –
@JonathanDursi - 这就是为什么你返回'请求' - 确保数据在您再次调用之前已经发送。你还应该怎么做这样的事情?当发送数据到'0'时,当前进程有很多事情要做......而且我不想等'0'太忙而无法立即接收消息......是不是全部“isend”的用途是以什么为开头? – mgilson
如果您必须手动处理检查先前的请求以确定是否可以调用此子例程,那么我只是看不到这个子例程的要点。如果你必须做一堆低级的东西才能安全地调用这个子程序,那么你并没有真正抽象出任何东西。也许你已经在代码中有了更高层次的内容,但仅仅看到这个例程很难说。如果你真的想这样做,我只是建议使用bsend(注意:不是ibsend,出于同样的原因)或者将它传递给一个缓冲区并让它安全地处理缓冲。 –