对 MPI_Barrier 的调用是不是会影响 MPI 进程中的每个线程?

Posted

技术标签:

【中文标题】对 MPI_Barrier 的调用是不是会影响 MPI 进程中的每个线程?【英文标题】:Does a call to MPI_Barrier affect every thread in an MPI process?对 MPI_Barrier 的调用是否会影响 MPI 进程中的每个线程? 【发布时间】:2011-07-25 07:32:46 【问题描述】:

对 MPI_Barrier 的调用会影响 MPI 进程中的每个线程还是仅影响线程 打电话? 供您参考,我的 MPI 应用程序将使用 MPI_THREAD_MULTIPLE 运行。

谢谢。

【问题讨论】:

【参考方案1】:

考虑这一点的方式是 MPI_Barrier(和其他集合)是阻塞函数调用,它阻塞直到通信器中的所有进程都完成了该函数。我认为,这使得弄清楚应该发生什么变得更容易一些。功能块,但其他线程不受阻碍地继续前进。

因此请考虑以下代码块(刷新共享done 标志以在线程之间进行通信不是您应该进行线程通信的方式,因此请不要将其用作任何模板。此外,使用参考done会解决this bug/optimization,见评论2的结尾):

#include <mpi.h>
#include <omp.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char**argv) 
    int ierr, size, rank;
    int provided;
    volatile int done=0;
    MPI_Comm comm;

    ierr = MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
    if (provided == MPI_THREAD_SINGLE) 
        fprintf(stderr,"Could not initialize with thread support\n");
        MPI_Abort(MPI_COMM_WORLD,1);
    

    comm = MPI_COMM_WORLD;
    ierr = MPI_Comm_size(comm, &size);
    ierr = MPI_Comm_rank(comm, &rank);

    if (rank == 1) sleep(10);

    #pragma omp parallel num_threads(2) default(none) shared(rank,comm,done)
    
        #pragma omp single
        
        /* spawn off one thread to do the barrier,... */
        #pragma omp task 
        
            MPI_Barrier(comm);
            printf("%d -- thread done Barrier\n", rank);
            done = 1;
            #pragma omp flush
        

        /* and another to do some printing while we're waiting */
        #pragma omp task
        
            int *p = &done;
            while(!(*p) 
                printf("%d -- thread waiting\n", rank);
                sleep(1);
            
        
        
    
    MPI_Finalize();

    return 0;

Rank 1 休眠 10 秒,所有 Rank 都在一个线程中启动屏障。如果您使用mpirun -np 2 运行此程序,您会期望排名为 0 的线程中的第一个线程会遇到障碍,而另一个线程会循环打印和等待——果然,这就是发生的情况:

$ mpirun -np 2 ./threadbarrier
0 -- thread waiting
0 -- thread waiting
0 -- thread waiting
0 -- thread waiting
0 -- thread waiting
0 -- thread waiting
0 -- thread waiting
0 -- thread waiting
0 -- thread waiting
0 -- thread waiting
1 -- thread waiting
0 -- thread done Barrier
1 -- thread done Barrier

【讨论】:

+1 就是一个很好的例子。对 Barrier 的调用只会阻塞调用它的线程,并不是所有线程都需要调用 Barrier 才能让进程完成调用。 知道为什么在我的情况下这个程序永远不会停止吗? (在 'while(!done)' 部分中,'done' 变量永远不会被读取为 1。我已经添加了 '#pragma omp flush (done)' 但它没有帮助。我的编译器 gcc 6.3.0 / Mac OS。

以上是关于对 MPI_Barrier 的调用是不是会影响 MPI 进程中的每个线程?的主要内容,如果未能解决你的问题,请参考以下文章

测试 MPI_Barrier C++

MPI_Barrier 在循环中不起作用

MPI_SEND 在 MPI_BARRIER 之后停止工作

MPI_BARRIER 不工作

请教个关于多线程调用webservice接口是不是会相互影响的问题

MPI 屏障 C++