例如,
if (rank == 0) {
MPI_Isend(&sendbuf, ..., 1, ..., &request);
MPI_Wait(&request, ...); /* Is this wait necessary? */
} else if (rank == 1) {
MPI_Irecv(&recvbuf, ..., 0, ..., &request);
MPI_Wait(&request, ...);
}
MPI_Isend后面的MPI_Wait是否必要?从理论上讲,
完成通信需要单独的发送完成呼叫。
但实际上,它可以在没有明确等待MPI_Isend的情况下工作。
答案 0 :(得分:5)
必须单独完成(例如MPI_Wait
)电话。
对于MPI_Isend
,完成确保消息已从发送缓冲区中复制出来。在消息完成之前,您不能修改或取消分配发送缓冲区。
同样,对于MPI_Irecv
,您必须完成调用以确保已在接收缓冲区中收到消息。在消息完成之前,您不能尝试从接收缓冲区中读取消息。显然,这意味着您不能写入或取消分配接收缓冲区。
消息完成由MPI_Wait
,成功MPI_Test
或多个完成(全部/任意/部分)变体完成。
除了完成通信外,这些功能还可以处理通信请求对象。从技术上讲,您无需使用MPI_Request_free
完成通信即可完成此操作。
根据您的有限代码示例,无法提供有关如何操作的建议。如果没有更多代码,就无法告诉您在哪里正确放置MPI_Wait
。如果您将其放在那里,代码是正确的,但您也可以使用MPI_Send
/ MPI_Recv
。
忽略消息完成将导致资源泄漏,并且很可能导致代码错误。
MPI很难,非阻塞MPI更难。如果您是初学者,请尝试坚持阻止MPI调用。非阻塞调用似乎被初学者过度使用,导致代码很难推理。也永远不要相信代码是正确的,只因为它适合你。