【问题标题】:Nonblocking MPI and rendezvous protocol非阻塞 MPI 和会合协议
【发布时间】:2022-01-02 08:56:39
【问题描述】:

我不完全理解 MPI 的非阻塞通信和集合协议应该如何交互。

首先,考虑这个伪代码,它在使用集合协议时会阻塞(假设我们有 2 个进程):

if (rank == 0) {
    MPI_Send (big_message, destination=1)
    MPI_Recv(source=1)
} else {
    MPI_Send(big_message, destination=0)
    MPI_Recv(source=0)
}

当消息太大而无法放入内部缓冲区时,这显然会阻塞,因为两个进程中的MPI_Sends 将等待发布匹配的接收。

在我的系统上,我发现以下修改可以工作:

if (rank == 0) {
    MPI_Isend (big_message, destination=1, &request)
    MPI_Recv(source=1)
    MPI_Wait(request)
} else {
    MPI_Isend(big_message, destination=0, &request)
    MPI_Recv(source=0)
    MPI_Wait(request)
}

我们使用非阻塞通信来发送消息。我的解决方案对 MPI 的每个实现都是正确的吗?我已经读过,当调用MPI_Isend 时,并没有强制要求实现启动任何形式的通信,并且可以在调用MPI_Wait 时执行它。这样的实现会破坏我的代码吗?我的理解是,在这种情况下,MPI_Isend 基本上是无操作的,并且对于我的代码,两个进程都会在MPI_Recv 中等待未发送的发送。

如果我的伪代码不可移植,有没有办法使用非阻塞通信来修复它?

【问题讨论】:

  • 您的解决方案是正确的,更好的解决方案是使用MPI_Sendrecv()。在后台,保证在MPI_Recv() 期间进行(足够的)通信(例如发送消息),这就是第二个版本永远不会挂起的原因。

标签: mpi deadlock


【解决方案1】:

说所有通信都可以在等待调用时发生是一种简单的观点,并且可能只有在所有通信都是非阻塞的情况下才是正确的。严格来说,这意味着您的代码将在阻塞接收上死锁,因为发送将发生在它们之后。这不会发生。

对于您的情况,标准的第 3.7.4 节说“[...] 对 MPI_Wait 的调用完成发送,如果匹配的接收已经开始,最终将返回 [...一些注释。 ..]" 所以,是的,你的代码是正确的。

【讨论】:

    猜你喜欢
    • 2023-03-28
    • 2021-07-24
    • 2015-08-17
    • 2012-08-24
    • 2021-12-13
    • 2011-05-25
    • 2021-12-30
    • 2013-01-25
    • 1970-01-01
    相关资源
    最近更新 更多