MPI_Reduce阻塞(或天然屏障)?

Cem*_*mre 7 parallel-processing mpi

我在C++中有下面的代码片段,它基本上使用经典的monte carlo技术来计算pi.

    srand48((unsigned)time(0) + my_rank);

    for(int i = 0 ; i < part_points; i++)
    {
            double x = drand48();

            double y = drand48();

            if( (pow(x,2)+pow(y,2)) < 1){ ++count; }
    }

    MPI_Reduce(&count, &total_hits, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);

    MPI_Barrier(MPI_COMM_WORLD);

    if(my_rank == root)
    {
            pi = 4*(total_hits/(double)total_points);

            cout << "Calculated pi: "  <<  pi << " in " << end_time-start_time <<  endl;
    }
Run Code Online (Sandbox Code Playgroud)

我只是想知道是否需要MPI_Barrier调用.MPI_Reduce是否确保在reduce操作完成之前不会执行if语句的主体?希望我很清楚.谢谢

sus*_*att 9

是的,所有集体通信呼叫(Reduce,Scatter,Gather等)都是阻塞的.没有障碍.

  • MPI 标准允许参与进程提前退出。唯一保证同步的集体调用是“MPI_Barrier”。 (2认同)

小智 5

阻止是的,障碍,不是。它调用是非常重要MPI_Barrier()MPI_Reduce()一个紧密循环执行的时候。如果不调用MPI_Barrier()reduce 进程的接收缓冲区,最终将运行满,应用程序将中止。而其他参与的进程只需要发送和继续,reduce 进程必须接收和reduce。上面的代码不需要障碍 if my_rank == root == 0(可能是真的)。无论如何......MPI_Reduce()不执行障碍或任何形式的同步。AFAIK 甚至MPI_Allreduce()不能保证同步(至少不是 MPI 标准)。

  • 由于此答案似乎与所选答案相矛盾,并且没有证据表明它已被否决,有人可以评论这是否实际上是错误的吗? (4认同)
  • 这个答案只对了一半。接收缓冲区**可能**已满。大多数 MPI 库都实现了流控制机制来防止这种情况发生。 (2认同)

Vic*_*out 5

问问自己是否需要这个障碍。假设你不是根;你调用Reduce,它会发送你的数据。有什么理由坐等根部得到结果吗?答:不,所以不需要屏障。

假设你是根。您发出reduce 调用。从语义上讲,您现在被迫坐下来等待结果完全组装完毕。那么为什么要设置障碍呢?同样,不需要障碍呼叫。

一般来说,您几乎不需要屏障,因为您不关心时间同步。语义保证您的本地状态在reduce 调用后是正确的。