2012-02-14 35 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調用後是正確的。