2012-02-14 36 views
6

我有C++下面的代码片段,它基本上使用经典的蒙特卡洛技术来计算pi。MPI_Reduce是否阻塞(或自然屏障)?

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; 
    } 

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

回答

7

是的,所有集体通信电话(减少,分散,聚集等)都被阻止。不需要屏障。

+0

MPI标准允许提前退出参与过程。保证同步的唯一集体调用是'MPI_Barrier'。 – 2015-04-15 08:55:15

2

阻挡是,屏障,否。在紧密循环中执行时,呼叫MPI_Barrier()对于MPI_Reduce()非常重要。如果不调用MPI_Barrier()还原进程的接收缓冲区最终将运行完毕并且应用程序将中止。虽然其他参与流程只需发送并继续,但减少流程必须接收和减少。 上述代码不需要屏障,如果my_rank == root == 0(可能是真的)。无论如何... MPI_Reduce()不会执行屏障或任何形式的同步。 AFAIK甚至MPI_Allreduce()不保证同步(至少不是由MPI标准)。

+3

由于这个答案似乎与选定的答案相矛盾,并且没有证据表明它已被拒绝,有人可以评论这是否实际上是错误的? – MarkWayne 2013-11-07 20:58:22

+0

这个答案只是一半正确的。接收缓冲区**可能**已满。大多数MPI库实现防止这种事情发生的流程控制机制。 – 2015-04-15 08:51:47

0

如果需要这个屏障,请问你自己。假设你不是根;你打电话给Reduce,它发送你的数据。是否有任何理由坐下来等到根源有结果?答:不,所以你不需要屏障。

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

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