【问题标题】:What happens when I MPI_Send to a process that has finished?当我 MPI_Send 到已完成的进程时会发生什么?
【发布时间】:2010-04-23 01:51:42
【问题描述】:

当我 MPI_Send 到已完成的进程时会发生什么?

我正在学习 MPI,并在 C 中编写了一个小型糖分布模拟。当工厂停止生产时,这些过程就结束了。当仓库空空如也时,它们就结束了。我可以通过查看 MPI_Send 的返回值来判断商店到仓库的订单是否没有成功(因为仓库流程已经结束)?文档没有提到针对这种情况的具体错误代码,但是成功时不会返回错误。

我能做到吗:

if (MPI_Send(...)) {
    ...
    /* destination has ended */
    ...
}

并且忽略错误代码?

谢谢

【问题讨论】:

  • 如答案中所述,该行为不是您可以依赖的任何东西。您所描述的内容与 MPI 的使用方式并不完全一致。相反,“仓库”流程应该保持活动状态,并通过指示仓库为空的内容明确回答无法完成的请求。
  • Novelcrat:您应该将其发布为答案。

标签: c concurrency mpi


【解决方案1】:

标准不允许使用不匹配的 MPI_Send 调用编写代码。除其他外,这意味着结果行为将取决于实现。可能的行为范围包括几个“明显”的选项:退出、挂起/死锁、内存损坏等。

大多数实现都有一定程度的调试输出,有助于跟踪这种逻辑编程错误。可以使用 MPI_Wait* 来阻止所有 MPI_Send/MPI_Recv 对的完成。在一般情况下,在接收节点进入 MPI_Finalize 之前,不可能知道 MPI_Send 不会被匹配。换句话说,在这种情况下使用屏障会导致程序挂起。

无论如何,这将是 MPI_Finalize 的错误条件。 MPI_Send 的目标等级应该被检测为已退出......因此 MPI_Send 永远无法匹配。但是,这种错误情况可能会导致 MPI 作业无法清理所有 rank 进程。

【讨论】:

    【解决方案2】:

    据我所知,MPI 标准没有为 MPI_Send() 定义任何返回值和输出参数:它不提供有关消息发送事件的任何信息,可能是因为消息缓冲可以使它没有调用返回时可获取有关结果的信息。

    如果你想让一个进程看到另一个进程何时结束,你应该在完成进程中发送一条带有指定标签的消息,并在另一个进程中定期发布nonblocking receives,以查看是否发送了退出通知。

    或者,如果你想让整个程序在一个进程停止时中止,最简单的做法是在结束进程中简单地调用 MPI_Abort(),以 MPI_COMM_WORLD 作为通信器,这样可以保证关闭所有进程。

    编辑:要实际回答标题中的问题,“当我 MPI_Send 到已完成的进程时会发生什么?”:据我了解,这取决于是否使用缓冲。如果不使用缓冲,则程序将挂起。如果使用缓冲,则 MPI_Send() 将缓冲消息并且进程将继续运行,但由于永远不会发布匹配的接收,因此消息将永远不会离开缓冲区。经常这样做最终会导致程序内存不足。

    【讨论】:

    • 谢谢,我还是试试这个。顺便说一句,我认为不返回任何内容的 MPI_Send 是 C++ 版本。根据mcs.anl.gov/research/projects/mpi/www/www3/MPI_Send.html 的文档,“所有 MPI 例程(MPI_Wtime 和 MPI_Wtick 除外)都返回错误值;C 例程作为函数的值”。
    • 在那些可能的返回值中,MPI_ERR_TAG 是我能想象到的唯一有用的返回值,但前提是 MPI_Send() 不遗余力地检查一个进程是否在提供的标签中提供了标签通讯器实际上正在运行。我的猜测是它不会这样做,并且 MPI_ERR_TAG 仅在提供的标签超出有效标签值范围时返回,但您可以使用简单的测试程序轻松验证这一点。
    猜你喜欢
    • 2019-10-27
    • 2012-06-06
    • 2015-01-29
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-17
    相关资源
    最近更新 更多