【问题标题】:What is the difference between MPI_Send() and MPI_Isend() followed by MPI_Wait()?MPI_Send() 和 MPI_Isend() 后跟 MPI_Wait() 有什么区别?
【发布时间】:2021-02-14 08:09:14
【问题描述】:

我无法理解MPI_Send()MPI_Isend() 后跟MPI_Wait() 之间的区别。

当我们在MPI_Isend() 之后使用MPI_Wait() 时,我们不是把它变成了阻塞调用吗?因为我们必须等到所有元素都复制到缓冲区中。

我知道这个配置(如下所示)可能会导致死锁

  P1--> MPI_Send() MPI_Recv()             
  P2--> MPI_Send() MPI_Recv()

但是这种配置(如下所示)也会导致死锁吗?

 P1--> MPI_Isend() MPI_Wait() MPI_Recv()             
 P2--> MPI_Isend() MPI_Wait() MPI_Recv()

【问题讨论】:

    标签: performance parallel-processing mpi wait hpc


    【解决方案1】:

    TL;DR:你需要使用MPI_Wait(或者使用MPI_Test来测试请求是否完成)来确保消息完成,并且数据在可以再次安全地操作发送/接收缓冲区。

    更详细的答案

    MPI_Isend

    开始非阻塞发送

    int MPI_Isend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request)

    让我们假设您使用MPI_Isend 发送ints 数组,而没有调用MPI_Wait;在这种情况下,您不确定何时可以安全地 修改(或释放内存)该数组。这同样适用于MPI_Irecv。尽管如此,调用MPI_Wait 可确保从那时起读取/写入(或释放内存)缓冲区,而不会出现undefined behavior 或不一致数据的风险。

    MPI_Isend 期间,缓冲区的内容(例如ints 的数组)必须被读取和发送;同样在MPI_Irecv 期间,接收缓冲区的内容必须到达。同时,可以将一些计算与正在进行的进程重叠,但是这种计算不能改变(或读取)发送/接收缓冲区的竞争。然后调用MPI_Wait 以确保从那时起数据发送/接收可以安全地读取/修改而不会出现任何问题。

    我无法理解 MPI_Send() 和 MPI_Isend() 后跟 MPI_Wait()。

    从这个SO Thread可以读到:

    这些函数不会返回(即它们阻塞),直到 通讯结束。稍微简化一下,这意味着 传递给 MPI_Send() 的缓冲区可以重复使用,因为 MPI 保存了它 某处,或因为它已被目的地接收。

    最后:

    我知道这个配置(如下所示)可能会导致死锁

    P1--> MPI_Send() MPI_Recv()
    P2--> MPI_Send() MPI_Recv()

    但是这种配置(如下所示)也会导致死锁吗?

    P1--> MPI_Isend() MPI_Wait() MPI_Recv()
    P2--> MPI_Isend() MPI_Wait() MPI_Recv()

    如果消息交换只发生在进程P1P2 之间,那么是的。 语义调用MPI_Isend() 后调用MPI_Wait() 与调用MPI_Send() 相同。

    P1P2 发送一条消息并等待该消息完成,但是P2P1 发送一条消息并等待。由于每个进程都在相互等待,这会导致死锁。

    【讨论】:

      【解决方案2】:

      当您使用MPI_Isend + MPI_Wait 时,您可以将通信与计算重叠:

      MPI_Isend(...) // Non blocking send
      
      // Perform computation here (make sure you don't use the buffer you're sending!)
      
      MPI_Wait(...)
      

      上面,当您的数据被发送给收件人时,MPI_Isend 下面的代码将执行(因为 MPI_Isend 是非阻塞的)。这允许您在通信发生时进行计算。与此不同,MPI_Send() 是不同的,因为它是阻塞的,因此您无法在通信发生时执行计算,就像上面使用 MPI_Isend 后跟 MPI_Wait 的代码一样。

      【讨论】:

      • “不要使用你发送的缓冲区”我认为只读访问是好的,不是吗?
      猜你喜欢
      • 1970-01-01
      • 2013-07-08
      • 1970-01-01
      • 1970-01-01
      • 2012-05-28
      • 2019-08-26
      • 2018-02-27
      • 1970-01-01
      • 2013-07-09
      相关资源
      最近更新 更多