我已经阅读了所有与之相关的MPI文档和教程以及Stack Overflow问题,但是我仍然不完全理解“完成” MPI_Isend时MPI_Wait的行为。我们可以简要总结一下吗?可以

  • A.在相应的Isend中使用的缓冲区可用时返回
    再一次(我想是的,但这并不能告诉我我想要的一切
    知道)。
  • B.相应的Recv完成时返回(我认为不是
    一定,但是有时候如果消息很大的话?)
  • C.确保Recv在返回
  • 后可以在以后的接收过程中完成

    我问是因为我正在尝试实现一种非阻塞广播(因为MPI_Ibcast是MPI 3,并且在我实际遇到的任何实现中都不存在)。我目前在每个进程上遵循的顺序是:

    从每个进程到每个其他进程的
  • MPI_Isend
  • 做其他工作
  • MPI_Wait,所有Isends为“complete”,无论这意味着
  • MPI_Recv所有消息

  • 这在实践中似乎可以正常工作,但是我不知道是否可以保证正常工作,或者我是否很幸运,因为我的消息很小(每个消息只有一个int,所以我怀疑它们很快就被MPI放入一些内部缓冲区或其他内容)。我不知道如果消息更大,是否会产生死锁(我担心在这种情况下,并非所有的MPI_Waits都会返回,因为有些可能会死锁,等待MPI_Recvs在另一个进程中发生)。

    如果不能保证总体上可以正常工作,是否至少可以保证只处理很小的消息?甚至不一定是真的吗?我真的不确定在这里我能指望什么。

    如果不能保证工作正常,那么如何实现无阻塞广播?也许会有一些巧妙的顺序执行等待和接收?就像第一个等级0等待等级1到Recv,然后等级1等待等级0到Recv?这样的交换配对安排更正确吗?

    最佳答案

    您的条件通过以下方式得到满足:
    MPI_IsendMPI_Wait都完成了:



    如果要使用MPI_IssendMPI_Wait:



    MPI_Send之后,以下是正确的:



    在建议的非阻塞广播中,您必须允许交换3.和4.,否则会出现死锁。这就是说,绝对没有严格的条件,即4.发生在3.之后。由于3发生在根上,而4发生在所有其他列上,所以这甚至不是问题。

    但是,我建议改用更清洁的方法:

    根目录上的

  • MPI_Isend所有进程
  • 根目录上的** all88进程上的
  • MPI_Irecv
  • (在所有进程上)做其他工作
  • 所有等级上所有已发布请求(MPI_Waitall / send)的
  • recv
    实现和工作应该是干净的。当然,这不是一个优化的集体……但这是另一个主题。

    关于c++ - MPI_Isend之后MPI_Wait的确切行为是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57970356/

  • 10-17 01:33