【问题标题】:Why does MPI_Sendrecv block?为什么 MPI_Sendrecv 会阻塞?
【发布时间】:2012-08-23 12:18:03
【问题描述】:

假设我有 n 个进程,每个进程都拥有一个本地数据,比如一个 int

现在我想重新实现 MPI_Allreduce() 函数,即计算所有这些 ints 的全局总和,然后将结果总和广播回进程。

我尝试在下面的代码中这样做:

  int temp;
  int my_sum = temp = my_data;
  for (int i = 1; i < size; ++i) {
    int partner = (my_rank + 1) % size;
    MPI_Sendrecv_replace(&temp, 1, MPI_INT, 
                         partner, 0, 
                         my_rank, 0, 
                         MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    my_sum += temp;
  }

以便进程以环形方式进行通信,但它是阻塞的。为什么?如何更改代码以使其正常工作?

注意:请不要建议问题的替代(更好)解决方案(显然,其中之一是使用 MPI_Allreduce() 函数)。我的目标是了解为什么这段代码 sn-p 不能按我认为的那样工作。

【问题讨论】:

    标签: c parallel-processing mpi


    【解决方案1】:

    每个人都在尝试从自己接收,但他们正在发送到partner;因为partner 将永远不会收到正在发送的消息,而my_rank 将永远不会从这里收到自己的消息,所以出现了挂起。

    如果您尝试向parter 发送数据,那么您需要确保partner 正在从您那里接收,这意味着每个人都需要从(myrank - 1 + size) % size 接收:

    int spartner = (my_rank + 1) % size;
    int rpartner = (my_rank - 1 + size) % size;
    MPI_Sendrecv_replace(&temp, 1, MPI_INT,
                         spartner, i,
                         rpartner, i,
                         MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    

    这样,在每次迭代中,rank 3(比如说)发送到 4,rank 4 从 rank 3 接收,因此 sendrecv 完成。 (我还冒昧地为循环中的每个迭代提供了自己的标签,这在这里并不是必需的,但如果存在其他不匹配的消息类型错误,通常有助于发现错误。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-10
      • 2017-07-14
      • 2010-10-13
      • 1970-01-01
      • 2019-02-18
      • 2021-08-29
      相关资源
      最近更新 更多