MPI_Barrier 在循环中不起作用

Posted

技术标签:

【中文标题】MPI_Barrier 在循环中不起作用【英文标题】:MPI_Barrier not working inside a loop 【发布时间】:2011-10-14 00:19:55 【问题描述】:

我对 MPI 函数进行了一些测试,以了解它是如何工作的,并且使用 MPI_Barrier 得到了一个奇怪的结果:如果我在类似代码中使用它,它会达到每个人的预期

int main(int argc, char *argv[])

  <some code>
  MPI_Barrier(MPI_COMM_WORLD);
  <more code>
  MPI_Barrier(MPI_COMM_WORLD);
  <...>

但是当我从循环内部调用它时,我会得到随机结果。具体来说,我有以下测试代码:

#include "mpi.h" 
#include <stdio.h>

int main(int argc, char *argv[]) 
 
  int i, rb, rank, nprocs;

  MPI_Init(&argc,&argv); 
  MPI_Comm_size(MPI_COMM_WORLD,&nprocs); 
  MPI_Comm_rank(MPI_COMM_WORLD,&rank);

  i=0;
  while(i<5)
  
    rb=MPI_Barrier(MPI_COMM_WORLD);
    printf("Itartion %d.  I am %d of %d. MPIBarrierRes: %d\n", i, rank, nprocs, rb);
    i++;
   
  MPI_Finalize(); 
  return 0; 
 

当我用 3 个任务运行它时,我随机得到:

Itartion 0.  I am 0 of 3. MPIBarrierRes: 0
Itartion 0.  I am 2 of 3. MPIBarrierRes: 0
Itartion 0.  I am 1 of 3. MPIBarrierRes: 0
Itartion 1.  I am 0 of 3. MPIBarrierRes: 0
Itartion 1.  I am 1 of 3. MPIBarrierRes: 0
Itartion 1.  I am 2 of 3. MPIBarrierRes: 0
Itartion 2.  I am 0 of 3. MPIBarrierRes: 0
Itartion 2.  I am 1 of 3. MPIBarrierRes: 0
Itartion 2.  I am 2 of 3. MPIBarrierRes: 0
Itartion 3.  I am 0 of 3. MPIBarrierRes: 0
Itartion 3.  I am 1 of 3. MPIBarrierRes: 0
Itartion 3.  I am 2 of 3. MPIBarrierRes: 0
Itartion 4.  I am 0 of 3. MPIBarrierRes: 0
Itartion 4.  I am 1 of 3. MPIBarrierRes: 0
Itartion 4.  I am 2 of 3. MPIBarrierRes: 0

这是我所期望的,或者只是相反:

Itartion 0.  I am 2 of 3. MPIBarrierRes: 0
Itartion 1.  I am 2 of 3. MPIBarrierRes: 0
Itartion 2.  I am 2 of 3. MPIBarrierRes: 0
Itartion 3.  I am 2 of 3. MPIBarrierRes: 0
Itartion 4.  I am 2 of 3. MPIBarrierRes: 0
Itartion 0.  I am 0 of 3. MPIBarrierRes: 0
Itartion 1.  I am 0 of 3. MPIBarrierRes: 0
Itartion 2.  I am 0 of 3. MPIBarrierRes: 0
Itartion 3.  I am 0 of 3. MPIBarrierRes: 0
Itartion 4.  I am 0 of 3. MPIBarrierRes: 0
Itartion 0.  I am 1 of 3. MPIBarrierRes: 0
Itartion 1.  I am 1 of 3. MPIBarrierRes: 0
Itartion 2.  I am 1 of 3. MPIBarrierRes: 0
Itartion 3.  I am 1 of 3. MPIBarrierRes: 0
Itartion 4.  I am 1 of 3. MPIBarrierRes: 0

或介于两者之间的东西,例如

Itartion 0.  I am 1 of 3. MPIBarrierRes: 0
Itartion 0.  I am 0 of 3. MPIBarrierRes: 0
Itartion 1.  I am 0 of 3. MPIBarrierRes: 0
Itartion 0.  I am 2 of 3. MPIBarrierRes: 0
Itartion 1.  I am 1 of 3. MPIBarrierRes: 0
Itartion 2.  I am 0 of 3. MPIBarrierRes: 0
Itartion 1.  I am 2 of 3. MPIBarrierRes: 0
Itartion 2.  I am 1 of 3. MPIBarrierRes: 0
Itartion 3.  I am 0 of 3. MPIBarrierRes: 0
Itartion 2.  I am 2 of 3. MPIBarrierRes: 0
Itartion 3.  I am 1 of 3. MPIBarrierRes: 0
Itartion 4.  I am 0 of 3. MPIBarrierRes: 0
Itartion 3.  I am 2 of 3. MPIBarrierRes: 0
Itartion 4.  I am 1 of 3. MPIBarrierRes: 0
Itartion 4.  I am 2 of 3. MPIBarrierRes: 0

谁能告诉我 MPI_Barrier 和循环之间是否存在冲突? (我只发现了在不同任务中使用不同大小的循环来避免死锁的警告。) 如果有,我能做些什么来强制任务在开始循环的新迭代之前相互等待? 如果没有,这段代码有什么问题?

谢谢!

【问题讨论】:

能否在 printf 语句下方放置另一个 MPI_Barrier 并检查问题是否仍然存在? 【参考方案1】:

这与您的循环无关。 MPI 没有暗示 IO 的顺序化。如果您需要按顺序打印出来,则必须明确将它们发送到一个等级,然后将它们全部打印在那里。

【讨论】:

谢谢!我添加了一些关于何时发送消息的信息,现在我可以看到它是如何工作的,尽管顺序仍然是随机的。我会尝试你对下一次测试的建议。

以上是关于MPI_Barrier 在循环中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的主循环在 tkinter 中不起作用?

范围在 for 循环中不起作用

如果循环在powershell函数中不起作用[关闭]

While循环在ResultSet java中不起作用

while 循环在 useEffect 挂钩中不起作用

Liquid - if contains 语句在 for 循环中不起作用