非阻塞 MPI 和会合协议
Posted
技术标签:
【中文标题】非阻塞 MPI 和会合协议【英文标题】:Nonblocking MPI and rendezvous protocol 【发布时间】: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_Send
s 将等待发布匹配的接收。
在我的系统上,我发现以下修改可以工作:
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()
期间进行(足够的)通信(例如发送消息),这就是第二个版本永远不会挂起的原因。
【参考方案1】:
说所有通信都可以在等待调用时发生是一种简单的观点,并且可能只有在所有通信都是非阻塞的情况下才是正确的。严格来说,这意味着您的代码将在阻塞接收上死锁,因为发送将发生在它们之后。这不会发生。
对于您的情况,标准的第 3.7.4 节说“[...] 对 MPI_Wait
的调用完成发送,如果匹配的接收已经开始,最终将返回 [...一些注释。 ..]" 所以,是的,你的代码是正确的。
【讨论】:
以上是关于非阻塞 MPI 和会合协议的主要内容,如果未能解决你的问题,请参考以下文章