是否需要在对应的 MPI_Recv 之前调用 MPI_Send

Posted

技术标签:

【中文标题】是否需要在对应的 MPI_Recv 之前调用 MPI_Send【英文标题】:Does MPI_Send need to be called before the corresponding MPI_Recv 【发布时间】:2014-11-27 19:11:31 【问题描述】:

我编写了一个程序,输出如下:

> mpiexec -n 3 "Poker Parallel Program.exe"
Entered slave. Rank: 1
Entered slave. Rank: 2
The program is about to do some statistical analysis of poker hands

Slave terminated: 1
Slave terminated: 2
Before recv. Proc number: 1
After slave send
After slave send
After recv. Proc number: 1
Before recv. Proc number: 2

一般的代码路径是这样的:

    在 master 中调用 Recv 两个从站发送 master 中的第一个 recv 解除阻塞 主块中的第二次接收

我只是想知道是否需要在发送之前进行 recv 调用?我不确定为什么我的 recv 调用会阻塞,否则。

【问题讨论】:

邮政编码!没有办法知道你的问题出在哪里,否则。 我可能应该有,但我只对问题中的具体行为感兴趣,而不是如何解决我的问题。 【参考方案1】:

在发送之前发布接收呼叫不是必需的,但如果这样做会更好。它也不太可能耗尽内存。

如果您的程序挂起时遇到问题,那可能不是因为您的排序错误。这可能是因为您没有拨打足够多的电话,或者它们没有正确匹配。

【讨论】:

谢谢,我就是这么想的。 这正是问题所在。我有一个挂起的 recv / 请求,我在某个时候使用 MPI_Cancel 在我的程序中取消了它,这解决了问题。 如果我们在没有 MPI_Send 的情况下调用 MPI_Recv 会发生什么?【参考方案2】:

正如 gTcV 在评论中所说,发布代码!

也就是说,这里有一些有用的一般建议:阅读MPI's communication modes。请注意,这里的“阻塞”并不意味着“等待匹配的接收”;这仅意味着当对MPI_Send() 的调用返回时,发送缓冲区对于调用者来说是安全的,可以重复使用。

标准模式发送MPI_Send() 允许(但不是必需)使用接收端缓冲来完成发送操作,即使尚未发布匹配的MPI_Recv()。这可能会引入一些细微的错误:在小范围内,一切似乎都可以正常工作,但一旦你扩大规模,接收端缓冲区就会填满,从而揭示以前隐藏的死锁条件。为了确保您的协议正确无误,在测试期间将每个标准模式MPI_Send() 更改为同步模式发送MPI_Ssend()。这意味着发送时不会使用缓冲;每个MPI_Ssend() 在返回之前等待匹配的MPI_Recv() 发布。当您确信一切正常且没有死锁时,将它们切换回MPI_Send()s 以提高性能。您可以使用 #define 宏,而不必搜索和替换每个实例。

【讨论】:

以上是关于是否需要在对应的 MPI_Recv 之前调用 MPI_Send的主要内容,如果未能解决你的问题,请参考以下文章

MPI_Recv:接收的大小与发送的大小不同

关于MPI_Send与MPI_Recv语义

MPI_Recv() 冻结程序,未从 C 中的 MPI_Send() 接收值

MPI_Recv 覆盖它不应访问的部分内存

线程中阻塞 MPI_Recv 的 CPU 使用率

发送数组时 MPI_Recv 发生错误