2014-02-07 82 views
6

我的理解是,一個主進程向所有其他進程發送消息。所有其他進程都會向主進程發送消息。這足以讓工作障礙了嗎?如果不是,那麼還需要什麼?在消息傳遞系統中如何實現屏障?

+0

「這將是足夠的屏障工作嗎?」 - 它工作嗎?你有沒有嘗試過?你面臨什麼問題? 「如果沒有,那還需要什麼?」 - 你告訴我們。 – Shoe

+0

對於每個完成消息接收(其客戶端發送,其次是阻斷)時,主運行是這樣的:如果'(++ atomic_variable> = n)的釋放();' – Damon

回答

7

讓我們來看看OpenMPI's implementation of barrier。雖然其他實現可能略有不同,但一般通信模式應該是相同的。

首先要注意的是,MPI的屏障沒有設置成本:達到MPI_Barrier呼叫的過程將被阻止,直到該組的所有其他成員也調用MPI_Barrier。需要注意的是MPI不要求他們達到相同電話,只是任何調用MPI_Barrier。因此,由於該組中的節點的總數爲每個進程已知,所以不需要分配額外的狀態來初始化該呼叫。

現在,讓我們來看看一些代碼:

/* 
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana 
*       University Research and Technology 
*       Corporation. All rights reserved. 
* Copyright (c) 2004-2005 The University of Tennessee and The University 
*       of Tennessee Research Foundation. All rights 
*       reserved. 
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, 
*       University of Stuttgart. All rights reserved. 
* Copyright (c) 2004-2005 The Regents of the University of California. 
*       All rights reserved. 
* Copyright (c) 2012  Oak Ridge National Labs. All rights reserved. 
* [...] 
*/ 

[...] 

/* 
* barrier_intra_lin 
* 
* Function: - barrier using O(N) algorithm 
* Accepts: - same as MPI_Barrier() 
* Returns: - MPI_SUCCESS or error code 
*/ 
int 
mca_coll_basic_barrier_intra_lin(struct ompi_communicator_t *comm, 
           mca_coll_base_module_t *module) 
{ 
    int i; 
    int err; 
    int size = ompi_comm_size(comm); 
    int rank = ompi_comm_rank(comm); 

首先節點(除了一個有等級0,根節點)派,他們已經到達屏障根節點的通知:

/* All non-root send & receive zero-length message. */ 

    if (rank > 0) { 
     err = 
      MCA_PML_CALL(send 
         (NULL, 0, MPI_BYTE, 0, MCA_COLL_BASE_TAG_BARRIER, 
          MCA_PML_BASE_SEND_STANDARD, comm)); 
     if (MPI_SUCCESS != err) { 
      return err; 
     } 

之後它們阻斷從根等待通知:

 err = 
      MCA_PML_CALL(recv 
         (NULL, 0, MPI_BYTE, 0, MCA_COLL_BASE_TAG_BARRIER, 
          comm, MPI_STATUS_IGNORE)); 
     if (MPI_SUCCESS != err) { 
      return err; 
     } 
    } 

根節點IM爲溝通的另一面辯解。首先,它阻止,直到它(組中的一個,從每一個節點,除了他自己,因爲他是阻隔調用內部已)收到n-1通知:

else { 
     for (i = 1; i < size; ++i) { 
      err = MCA_PML_CALL(recv(NULL, 0, MPI_BYTE, MPI_ANY_SOURCE, 
            MCA_COLL_BASE_TAG_BARRIER, 
            comm, MPI_STATUS_IGNORE)); 
      if (MPI_SUCCESS != err) { 
       return err; 
      } 
     } 

一旦所有通知已經到達時,它發出的消息,每節點正在等待,信令,每個人都已經到達屏障,在此之後它離開屏障呼叫本身:

 for (i = 1; i < size; ++i) { 
      err = 
       MCA_PML_CALL(send 
          (NULL, 0, MPI_BYTE, i, 
           MCA_COLL_BASE_TAG_BARRIER, 
           MCA_PML_BASE_SEND_STANDARD, comm)); 
      if (MPI_SUCCESS != err) { 
       return err; 
      } 
     } 
    } 

    /* All done */ 

    return MPI_SUCCESS; 
} 

所以通信模式是首先從到根的所有節點的n:1然後從根1:n回到所有節點。爲了避免使用請求重載根節點,OpenMPI允許使用基於樹的通信模式,但其基本思想是相同的:所有節點在進入屏障時通知根,而根聚合結果並在每個人準備繼續。

+1

謝謝你這麼清楚的解釋:)。 – MetallicPriest

1

不,這還不夠。一旦主進程向所有其他進程發送了一條消息,通知他們已經到達屏障,並且所有其他進程都回應說他們已經到達屏障,只有主進程知道所有進程已經到達屏障。在這種情況下,從主人到其他進程的另一個消息將是必要的。

我並沒有關於任何庫實際執行的MPI壁壘要求,特別是我不是暗示概述消息序列在實踐中使用,只是它在理論上是有缺陷的。

+0

見的是,主首先接收,然後發送。我在第一次閱讀時忽略了這個條件(等級> 0)。 –