MPI中异步发送的安全保证 [英] Safety guarantee for asynchronous sends in MPI
问题描述
在我的应用程序中,我使用MPI以主从方式分发作业.将作业交给从属,然后收集结果.在该程序的多线程版本中,当所有处理器同时尝试执行Send
(阻塞)时,由于没有匹配的Recv
,因此存在潜在的死锁.我想出了一个似乎可行的解决方案,但我想拥有保证书(而不是再测试一万次).
In my application I use MPI to distribute jobs in a master-slave fashion. A job is given to a slave and then results are collected. In a multi-threaded version of this program, there was a potential deadlock when all processors simultaneously try to Send
(blocking), because there was no matching Recv
. I came with up with a solution which seems to work, but I would like to have the guarantee (other than by testing it another ten thousand times).
我的程序的安全性是肯定的,如果可以保证提供的代码很少,请提供符合标准的实现. (显然,这仅适用于两个处理器,而不能用于更多处理器):
The safety of my program is certain, if this little code is guaranteed to be -- provided a conforming implementation. (obviously this works for two processors only and is not intended for more):
#include <cassert>
#include "mpi.h"
int main()
{
MPI::Init();
int ns[] = {-1, -1};
int rank = MPI::COMM_WORLD.Get_rank();
ns[rank] = rank;
MPI::Request request = MPI::COMM_WORLD.Isend(&rank, sizeof(int), MPI::BYTE, 1 - rank, 0);
MPI::COMM_WORLD.Recv(&ns[1 - rank], sizeof(int), MPI::BYTE, 1 - rank, 0);
request.Wait();
assert( ns[0] == 0 );
assert( ns[1] == 1 );
MPI::Finalize();
}
所以我的问题是:在Isend
返回的Request
上调用Wait
之前,Isend
与Recv
的交织是否是MPI中定义明确的安全内容?
So my question is: Is the interleaving of an Isend
with a Recv
until I call Wait
on the Request
returned by Isend
a well-defined safe thing in MPI?
(免责声明:这段代码不是为了异常安全或特别漂亮而设计的.仅用于演示目的)
(Disclaimer: This piece of code is not designed to be exception-safe or particularly beautiful. It's for demo purposes only)
推荐答案
您的代码绝对安全.这是由MPI标准§3.7.4-非阻塞通信的语义中定义的非阻塞操作的语义所保证的:
Your code is perfectly safe. This is guaranteed by the semantics of the non-blocking operations as defined in the MPI standard §3.7.4 - Semantics of Nonblocking Communications:
进度如果已启动匹配的发送,则对
MPI_WAIT
的调用将最终终止并返回,除非该发送被另一个接收满足. 特别是,如果匹配的发送是非阻塞的,则即使发送方未执行任何调用来完成发送,接收也应完成.类似地,对MPI_WAIT
的调用将最终完成发送如果已启动匹配的接收,则返回该值,除非该接收被另一个发送满足,并且即使没有执行任何调用来完成接收.
Progress A call to
MPI_WAIT
that completes a receive will eventually terminate and return if a matching send has been started, unless the send is satised by another receive. In particular, if the matching send is nonblocking, then the receive should complete even if no call is executed by the sender to complete the send. Similarly, a call toMPI_WAIT
that completes a send will eventually return if a matching receive has been started, unless the receive is satised by another send, and even if no call is executed to complete the receive.
在这种情况下,阻塞操作等效于启动非阻塞操作,然后立即等待.
A blocking operation in that context is equivalent to initiating a non-blocking one, immediately followed by a wait.
如果标准的措辞不够令人放心,则Open MPI中MPI_SENDRECV
实现中的以下代码节可能会有所帮助:
If the words of the standard are not reassuring enough, then this code section from the implementation of MPI_SENDRECV
in Open MPI might help:
if (source != MPI_PROC_NULL) { /* post recv */
rc = MCA_PML_CALL(irecv(recvbuf, recvcount, recvtype,
source, recvtag, comm, &req));
OMPI_ERRHANDLER_CHECK(rc, comm, rc, FUNC_NAME);
}
if (dest != MPI_PROC_NULL) { /* send */
rc = MCA_PML_CALL(send(sendbuf, sendcount, sendtype, dest,
sendtag, MCA_PML_BASE_SEND_STANDARD, comm));
OMPI_ERRHANDLER_CHECK(rc, comm, rc, FUNC_NAME);
}
if (source != MPI_PROC_NULL) { /* wait for recv */
rc = ompi_request_wait(&req, status);
} else {
if (MPI_STATUS_IGNORE != status) {
*status = ompi_request_empty.req_status;
}
rc = MPI_SUCCESS;
}
使用Irecv / Send / Wait(receive)
或Isend / Recv / Wait(send)
都没关系-当涉及到可能的死锁时,两者都同样安全.当然,如果交错操作未正确匹配,则可能(并且将)发生死锁.
It doesn't matter if you use Irecv / Send / Wait(receive)
or Isend / Recv / Wait(send)
- both are equally safe when it comes to possible deadlocks. Of course deadlocks could (and will) occur if the interleaved operation is not properly matched.
使代码不合格的唯一原因是它使用C ++ MPI绑定.这些在MPI-2.2中已弃用,在MPI-3.0中已删除.您应该改用C API.
The only thing that brings your code to non-conformance is the fact that it uses the C++ MPI bindings. Those were deprecated in MPI-2.2 and deleted in MPI-3.0. You should use the C API instead.
这篇关于MPI中异步发送的安全保证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!