【问题标题】:MPI_Isend/Recv- Is there a deadlock?MPI_Isend/Recv- 是否存在死锁?
【发布时间】:2011-06-01 01:25:21
【问题描述】:

我一共使用 MPI 在 4 个节点上传递了 8 条消息。我注意到有两条消息的数组没有提供有意义的结果。我复制了以下代码的摘录?这些是我根据以下代码/结果提出的一些相关问题:

  1. MPI_Isend 是否也需要等待?我不确定是否存在死锁。我还尝试将这两个变量从一个节点传递到另一个节点,但数组值仍然为 NULL。
  2. MPI_SendRecv 是否会按照此处Non Blocking communication in MPI and MPI Wait Issue. Not all information is passed correctly 的建议提高代码效率?如果是这样,如何/为什么?也将不胜感激有关设置的一些指示。

谢谢!

Source Code:

if ((my_rank) == 0)
{
MPI_Irecv(A, Rows, MPI_DOUBLE, my_rank+1, MPI_ANY_TAG, MPI_COMM_WORLD, &request[6]);
MPI_Wait(&request[6], &status[6]);
}


if ((my_rank) == 1)
{
MPI_Isend(AA, Rows, MPI_DOUBLE, my_rank-1, 0, MPI_COMM_WORLD, &request[6]);
}


if ((my_rank) == 2)
{
MPI_Isend(B, Rows, MPI_DOUBLE, my_rank+1, 0, MPI_COMM_WORLD, &request[7]);
}

if ((my_rank) == 3)
{
MPI_Irecv(BB, Rows, MPI_DOUBLE, my_rank-1, MPI_ANY_TAG, MPI_COMM_WORLD, &request[7]);
MPI_Wait(&request[7], &status[7]);
}

【问题讨论】:

  • 这里没有足够的上下文来弄清楚发生了什么。什么是 B、BB、A、AA、行?哪些变量在这里没有合理的值?你是什​​么意思数组值是NULL?演示问题的完整代码段是最好的。至于您的其他问题,是的,Isend 和 Irecv 都应该匹配等待或类似的,并且不,在这种特殊情况下,sendrecv 与给定的模式不匹配(在上述情况下,没有一个任务同时发送和接收)。
  • 谢谢乔纳森。我能够修复这个错误。它与我的打印方式有关,而不是发送/接收。命令。感谢您的帮助。

标签: c++ mpi


【解决方案1】:

是的,所有非阻塞调用(MPI_Isend、MPI_Irecv 等)都需要匹配的 MPI_Wait。在调用 MPI_Wait 之前,不能保证调用完成。在 MPI_Wait 返回之前,您不应更改缓冲区的内容。

https://computing.llnl.gov/tutorials/mpi/

要使用 SendRecv,相同的任务必须发送消息并等待接收消息。该模式不适用于您的代码。

【讨论】:

  • 能否请您详细说明“缓冲区的内容在 MPI_Wait 返回之前不得更改?”。由于 MPI_Isend/recv 是非阻塞命令,这意味着计算与通信同时发生,所以这是否意味着缓冲区正在动态更新?我不是很清楚。如果您确实澄清了,将不胜感激。谢谢!
  • S抱歉,回复晚了。非阻塞调用只保证它会尽快返回函数。它不保证实际发送/接收数据。这就是重要的区别。由于调用刚刚返回并且不能保证在返回时完成,我们不能重用缓冲区。把它想象成..这个函数刚刚启动了一个后台线程并返回。线程正在做发送/接收的工作。为保证工作已完成,您应该调用 MPI_Wait。它将一直阻塞,直到函数实际完成工作并完成。
  • 谢谢!我最终使用了阻塞发送/接收。在效率/时序方面,非阻塞比阻塞发送/接收更好吗?
  • 非阻塞的主要优点是您无需等待通信调用完成。您可以将通信与计算重叠并提高效率。但是如果你在通信过程中没有工作要做,CPU 只是在 MPI_Wait 中空闲。因此,利用提供的机制来提高效率取决于您的算法/程序结构。只是盲目地使用非阻塞与阻塞没有什么不同。
  • 谢谢!您的回复非常有用。
猜你喜欢
  • 1970-01-01
  • 2011-08-01
  • 2016-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 2019-02-23
  • 1970-01-01
相关资源
最近更新 更多