异步MPI通信的时间线

时间:2014-07-02 19:12:11

标签: asynchronous mpi

要优化MPI通信,了解整个通信过程的流程非常重要。这对于同步通信来说相当简单,但异步通信呢?据我了解,它可以通过以下两种方式之一工作:

  1. Rank0 - > Isend - > Rank1和Rank1 - > Isend - > Rank0
  2. Rank0 - > Irecv - > Rank1和Rank1 - > Irecv - > Rank0
  3. Rank0和Rank1做一些计算
  4. 正在将邮件分派到各自的目标位置
  5. 找到匹配的Recv电话! - >写入给定的recv-buffer
  6. Rank0和Rank1完成计算并调用MPI_Wait进行发送和接收
  7. MPI_Wait - >沟通完成
    1. Rank0 - > Isend - > Rank1和Rank1 - > Isend - > Rank0
    2. Rank0和Rank1做一些计算
    3. 正在将邮件分派到各自的目标位置
    4. 找不到匹配的Recv电话! - >分配自己的临时缓冲区并写入
    5. Rank0和Rank1完成计算并调用MPI_Recv
    6. 找到匹配的MPI_Recv调用 - >临时缓冲区被写入recv-buffer
    7. Rank0和Rank1致电MPI_Wait
    8. MPI_Wait - >通讯完成 - >释放临时缓冲区
    9. 这是对的吗?我是否需要了解在MPI背景下运行的任何其他进程以优化其使用?

1 个答案:

答案 0 :(得分:1)

通常,在使用MPI发送数据时,如果可能,您应该始终预先发布您的收据。这意味着如果你试图在两个进程之间进行通信,你应该做这样的事情(为简洁起见,遗漏了许多重要的论点):

if (rank == 0) {
  MPI_Irecv(rdata, ..., 1, ..., req[0]);
  ...
  MPI_Isend(sdata, ..., 1, ..., req[1]);
} else {
  MPI_Irecv(rdata, ..., 0, ..., req[0]);
  ...
  MPI_Isend(sdata, ..., 0, ..., req[1]);
}
MPI_Waitall(2, req);

如果您愿意,可以在IrecvIsend之间执行其他操作,但是通过预先发布接收,您将节省内存和时间,因为用户缓冲区可用于MPI用于存储数据的库。如果您不按此顺序执行此操作,并且在您致电Irecv(或任何其他接收方式)之前消息已到达,则消息将包含首先将其存储在某个其他内部缓冲区中,直到发布接收,然后将该消息再次从MPI缓冲区复制到用户缓冲区。如果消息太大而无法容纳在预先分配的缓冲区中,那么在调用接收之前,这也可能导致消息根本不被发送。

您也可以尽早致电Irecv。如果你想把Irecv放在迭代的开头,做一堆计算,然后在数据准备好的时候在迭代结束时调用Isend,这也很好

除非您有大量进程向一个进程发送消息,否则其他进程之间的串扰通常不是问题。在这种情况下,您最终可能会遇到一些流量控制问题,但这种情况通常不会出现。在这种情况下,大部分时间都使用集体而不是点对点通信。