【发布时间】: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()期间进行(足够的)通信(例如发送消息),这就是第二个版本永远不会挂起的原因。