MPI中异步发送的安全保证 [英] Safety guarantee for asynchronous sends in MPI

查看:121
本文介绍了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之前,IsendRecv的交织是否是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 to MPI_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆