为什么MPI_Sendrecv阻止?

时间:2012-08-28 22:46:29

标签: c parallel-processing mpi

假设我有 n 进程,并且每个进程都拥有一段本地数据,例如 int

现在我想重新实现 MPI_Allreduce()功能,即计算所有整数的全局总和,然后将结果总和广播回流程。

我尝试在下面的代码中执行此操作:

  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()功能)。我的目标是理解为什么这段代码片段无法正常工作。

1 个答案:

答案 0 :(得分:6)

每个人都试图从自己那里得到,但他们正在向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);

这样,等级3(比方说)发送到4,等级4在每次迭代时从等级3接收,因此sendrecv完成。 (我也冒昧地通过循环给每个迭代它自己的标记,这在这里不是必需的,但如果存在其他不匹配消息类型错误,通常会帮助查找错误。)