OpenMPI MPI_Barrier问题

我使用MPI_Barrier的OpenMPI实现有一些同步问题:

int rank; int nprocs; int rc = MPI_Init(&argc, &argv); if(rc != MPI_SUCCESS) { fprintf(stderr, "Unable to set up MPI"); MPI_Abort(MPI_COMM_WORLD, rc); } MPI_Comm_size(MPI_COMM_WORLD, &nprocs); MPI_Comm_rank(MPI_COMM_WORLD, &rank); printf("P%d\n", rank); fflush(stdout); MPI_Barrier(MPI_COMM_WORLD); printf("P%d again\n", rank); MPI_Finalize(); 

对于mpirun -n 2 ./a.out

输出应为:P0 P1 …

有时输出:P0 P0再次P1 P1

这是怎么回事?

打印输出行在终端上显示的顺序不一定是打印内容的顺序。 您正在使用共享资源( stdout ),因此总是必须存在排序问题。 (并且fflush在这里没有帮助, stdout无论如何都是行缓冲的。)

您可以尝试使用时间戳为输出添加前缀,并将所有这些保存到不同的文件中,每个MPI进程一个。

然后,要检查您的日志,您可以将两个文件合并在一起,并根据时间戳进行排序。

那么你的问题应该会消失。

MPI_Barrier()没有任何问题。

正如Jens所提到的 ,你没有看到预期输出的原因是因为stdout在每个进程上都被缓冲了。 无法保证来自多个进程的打印将按顺序显示在调用进程中。 (如果每个进程的stdout被转移到主进程实时打印,那将导致大量不必要的通信!)

如果您想说服自己屏障有效,您可以尝试写入文件。 将多个进程写入单个文件可能会导致额外的复杂性,因此您可以将每个proc写入一个文件,然后在屏障之后交换它们写入的文件。 例如:

  Proc-0 Proc-1 | | f0.write(..) f1.write(...) | | x ~~ barrier ~~ x | | f1.write(..) f0.write(...) | | END END 

示例实施:

 #include "mpi.h" #include  #include  int main(int argc, char **argv) { char filename[20]; int rank, size; FILE *fp; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); if (rank < 2) { /* proc 0 and 1 only */ sprintf(filename, "file_%d.out", rank); fp = fopen(filename, "w"); fprintf(fp, "P%d: before Barrier\n", rank); fclose(fp); } MPI_Barrier(MPI_COMM_WORLD); if (rank < 2) { /* proc 0 and 1 only */ sprintf(filename, "file_%d.out", (rank==0)?1:0 ); fp = fopen(filename, "a"); fprintf(fp, "P%d: after Barrier\n", rank); fclose(fp); } MPI_Finalize(); return 0; } 

运行代码后,您应该得到以下结果:

 [me@home]$ cat file_0.out P0: before Barrier P1: after Barrier [me@home]$ cat file_1.out P1: before Barrier P0: after Barrier 

对于所有文件,“后障碍”语句将始终显示在以后。

MPI程序无法保证输出顺序。

这根本与MPI_Barrier无关。

此外,我不会花太多时间来担心MPI程序的输出排序。

如果你真的想要,最优雅的方法就是让流程将他们的消息发送到一个等级,比如排名0,让等级0按照接收顺序或排序顺序打印输出。

再次,不要花太多时间尝试从MPI程序订购输出。 它不实用,用处不大。