C OpenMPI\U屏障问题

C OpenMPI\U屏障问题,c,mpi,openmpi,C,Mpi,Openmpi,我在使用MPI_屏障的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

我在使用MPI_屏障的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();
对于MPI运行-n 2./a.out

输出应为: P0 P1 ...

输出有时是: P0 P0再次出现 P1 又是P1


发生什么事了

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

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

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


那么,您的问题应该会消失。

MPI_Barrier()没有问题

同样,之所以看不到预期的输出,是因为每个进程都缓冲了stdout。无法保证来自多个进程的打印将按顺序显示在调用进程上。(如果每个进程的stdout被实时传输到主进程进行打印,将导致大量不必要的通信!)

如果你想让自己相信这个障碍是有效的,你可以试着写一个文件。将多个进程写入单个文件可能会导致额外的复杂性,因此您可以让每个进程写入一个文件,然后在屏障后交换它们写入的文件。例如:

    Proc-0           Proc-1
      |                 |
 f0.write(..)     f1.write(...) 
      |                 |
      x  ~~ barrier ~~  x
      |                 |
 f1.write(..)     f0.write(...) 
      |                 |
     END               END
示例实现:

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

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;

}

对于所有文件,“屏障后”语句将始终稍后出现。

MPI程序中不保证输出顺序

这与MPI_屏障无关

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

如果您真的愿意,实现这一点最优雅的方法是让进程将其消息发送到一个列组,例如,列组0,并让列组0按照接收它们的顺序或按列组的顺序打印输出


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

除了前面的答案之外,您的MPI\U屏障工作正常


不过,如果您只是想看到它工作,可以强制暂停执行(
SLEEP(1)
)一段时间,让输出赶上。

如果MPI进程在不同的节点上运行,依赖时间戳可能并不理想,除非您能保证时钟同步。@Shawn:有MPI\u Wtime()为此,@suszterpatt:
MPI\u Wtime()
通常不是全局/同步时钟!(仅当定义了MPI\u WTIME\u是全局的且为真时)好的,OpenMPI中的MPI\u WTIME不同步。
[me@home]$ cat file_0.out
P0: before Barrier
P1: after Barrier

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