2011-08-05 62 views
4

在MPI,是MPI_Bcast純粹是一個方便的功能或者是有效率優勢,使用它,而不是僅僅遍歷所有的行列,併發送相同的消息給所有的人?MPI_Bcast:效率優勢?

理由:MPI_Bcast將消息發送給每個人(包括根)的行爲對我來說都不方便,所以我寧願不使用它,除非有充分的理由,否則可以不發送消息爲根。

+0

爲什麼要讓MPI_Bcast的根參與問題? –

回答

7

使用MPI_Bcast絕對會比滾動自己更有效率。在所有MPI實施中已經完成了大量工作,以基於諸​​如消息大小和通信體系結構等因素來優化集體操作。

例如,MPI_Bcast in MPICH2 would use a different algorithm depending on the size of the message。對於短消息,使用二叉樹來最小化處理負載和延遲。對於長消息,它被實現爲一個二叉樹分散後跟一個全集。另外,HPC供應商通常提供MPI實現,以有效利用底層互連,尤其是對於集體操作。例如,可以使用hardware supported multicast schemeuse bespoke algorithms that can take advantage of the existing interconnects

2

MPI_Bcast通過定義將消息從一個進程('root')發送到所有其他。它可能會比循環遍歷所有流程快一點。例如,mpich2實現使用二叉樹來分發消息。

如果你不想廣播到MPI_COMM_WORLD,但要定義分組,你可以去像這樣:

#include <stdio.h> 
#include "mpi.h" 

#define NPROCS 8 

int main(int argc, char **argv) 
{ 
    int rank, new_rank, sendbuf, recvbuf, 
    ranks1[4]={0,1,2,3}, ranks2[4]={4,5,6,7}; 

    MPI_Group orig_group, new_group; 
    MPI_Comm new_comm; 

    MPI_Init(&argc,&argv); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
    sendbuf = rank; 

    /* Extract the original group handle */ 
    MPI_Comm_group(MPI_COMM_WORLD, &orig_group); 

    /* Divide tasks into two groups based on rank */ 
    if (rank < NPROCS/2) { 
     MPI_Group_incl(orig_group, NPROCS/2, ranks1, &new_group); 
    } else { 
     MPI_Group_incl(orig_group, NPROCS/2, ranks2, &new_group); 
    } 

    /* Create new communicator and then perform some comm 
    * Here, MPI_Allreduce, but you can MPI_Bcast at will 
    */ 
    MPI_Comm_create(MPI_COMM_WORLD, new_group, &new_comm); 
    MPI_Allreduce(&sendbuf, &recvbuf, 1, MPI_INT, MPI_SUM, new_comm); 
    MPI_Group_rank (new_group, &new_rank); 

    printf("rank= %d newrank= %d recvbuf= %d\n", rank, new_rank, recvbuf); 

    MPI_Finalize(); 
} 

這可能會產生類似以下的輸出:

rank= 7 newrank= 3 recvbuf= 22 
rank= 0 newrank= 0 recvbuf= 6 
rank= 1 newrank= 1 recvbuf= 6 
rank= 2 newrank= 2 recvbuf= 6 
rank= 6 newrank= 2 recvbuf= 22 
rank= 3 newrank= 3 recvbuf= 6 
rank= 4 newrank= 0 recvbuf= 22 
rank= 5 newrank= 1 recvbuf= 22 
3

集體通信可以是比自己滾動更快。所有的MPI實踐都花費了大量的時間來處理這些例程以加快速度。

如果您經常想要做集體類型的事情,但只在一部分任務上,那麼您可能需要創建自己的子通信器,並在這些通信器上使用BCAST等。

+0

關於使用子通信器的好處。 +1 –

+0

即使有一個替代comm,該comm的根仍將參與集體操作。 OP特別提到,讓根獲得信息是一個問題。 –

+1

將消息「發送」給自己的根是空操作,甚至不是內存副本。 –

2

的答案是MPI_Bcast可能比一個循環更快,在一般情況下。一般來說,MPI集體針對各種消息大小,通信大小和特定排名佈局進行了優化。

也就是說,有可能在特定的郵件大小,通信大小和排名佈局上擊敗集體。例如,對非阻塞點對點調用(例如ISend和Recv/IRecv)的循環可能會更快......但可能只是在某些特定的消息大小,通信大小和排名佈局上。

如果您正在編碼的特定算法需要Bcast模式(例如,所有等級從根獲得相同的數據有效載荷),則使用Bcast集合。一般來說,通過滾動你自己的「集體替換」是不值得增加複雜性的。

如果還有其他的算法需要的消息模式,以及只有部分擬合的Bcast ...那麼它可能是值得推出自己的...但個人而言,我個人設置的酒吧相當高。

+0

我同意。 \t 只需調整集體參數(手動通過命令行參數/環境變量,或通過類似於英特爾MPI的mpitune自動調整),然後重寫自己的高性能集體,就更容易了。 –