MPI基礎內容介紹


MPI 基礎內容

1. MPI基本函數

1.1 初始化

int MPI_Init(int *argc, char ** argv)

通過MPI_Init進入MPI環境,並完成初始化工作。

1.2 結束

int MPI_Finalize(void)

從MPI環境中退出

1.3 獲取進程編號

int MPI_Comm_rank(MPI_Comm comm, int *rank)

獲取當前進程在指定通信域中的編號,其中MPI_Comm代表一個通信域。一個通信域指的是一個進程組和對應的通信上下文,常用的常量MPI_COMM_World是所有進程在的通信域。編號保存在變量rank中。

1.4 獲取進程數目

int MPI_Comm_size(MPI_Comm comm, int *size)

獲得當前通信域中的進程數目,數目保存在變量size中。

1.5 發送消息

int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)

參數buf指的是要發送內容的首地址,count指的是發送的元素數目。datatype指的是要發送的數據類型,C語言中的數據類型,會與MPI的數據類型綁定,比如int會在MPI中綁定為MPI_INT。MPI預定義的數據類型表如下(部分內容):

MPI(C語言綁定) C語言中的數據類型
MPI_BYTE
MPI_DOUBLE double
MPI_FLOAT float
MPI_INT int
MPI_UNSIGNED_CHAR unsigned char
MPI_CHAR signed char

消息信封指的是<源/目的地址(source/dest),消息標簽(tag),通信域(MPI_Comm)>,表示接收/發送消息的地址。其中source/dest指的是源/目的進程的進程號,即從函數MPI_Comm_rank 中獲得的rank值。

1.6 接收消息

int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status)

變量status指的是返回狀態。在C語言中,狀態變量至少是由三部分組成的數據結構類型,這三個部分分別是MPI_SOURCE,MPI_TAG和MPI_ERROR,還可以包含其他部分。傳遞MPI_Status參數時,需用語句MPI_Status status;生成一個MPI_Status類型的變量,然后將地址傳入。

1.7 簡單示例

一個簡單的MPI示例如下

#include "mpi.h" /*MPI頭函數,提供了MPI函數和數據類型定義*/
int main( int argc, char** argv )
{
    int rank, size, tag=1;
    int senddata,recvdata;
    MPI_Status status; 
    MPI_Init(&argc, &argv); /*MPI的初始化函數*/
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); /*該進程編號*/
    MPI_Comm_size(MPI_COMM_WORLD, &size); /*總進程數目*/
    if (rank==0){
        senddata=9999; 
        MPI_Send( &senddata, 1, MPI_INT, 1, tag, MPI_COMM_WORLD); /*發送數據到進程1*/
    }
    if (rank==1) 
    	MPI_Recv(&recvdata, 1, MPI_INT, 0, tag, MPI_COMM_WORLD, &status); /*從進程0接收數據*/
    MPI_Finalize(); /*MPI的結束函數*/
    return (0);
}

2. 通信方式

2.1 通信域

通信域(Communicator)包括進程組(Process Group)和通信上下文等內容,用於描述通信進程之間的關系。進程組是進程的有限有序集合,集合的數目稱為進程組的大小,在一個大小為n的進程組中,進程按照0,1,2,……,n-1進行排列。通信上下文不是顯示的對象,只是作為通信域的一部分出現,用於安全的區別不同的通信以免互相干擾。MPI_COMM_WORLD是所有進程的集合。

通信域分為組內通信域和組間通信域,分別用來實現MPI的組內通信(Intra-communication)組間通信(Inter-communication)

2.2 管理通信域

常見的用於管理通信域的函數如下

函數名 含義
MPI_Comm_size 獲取指定通信域中進程的個數
MPI_Comm_rank 獲取當前進程在指定通信域中的編號
MPI_Comm_compare 對給定的兩個通信域進行比較
MPI_Comm_dup 復制一個已有的通信域生成一個新的通信域,兩者除通信上下文不同外,其它都一樣。
MPI_Comm_create 根據給定的進程組創建一個新的通信域
MPI_Comm_split 從一個指定通信域分裂出多個子通信域,每個子通信域中的進程都是原通信域中的進程。
MPI_Comm_free 釋放一個通信域

一個在MPI中創建新通信域的例子

MPI_Comm MyWorld, SplitWorld;
int my_rank,group_size, Color, Key;
MPI_Init(&argc, &argv);
MPI_Comm_dup(MPI_COMM_WORLD,&MyWorld);
MPI_Comm_rank(MyWorld,&my_rank);
MPI_Comm_size(MyWorld,&group_size);
Color=my_rank%3;
Key=my_rank/3;
MPI_Comm_split(MyWorld,Color,Key,&SplitWorld);

解釋如下

  • MPI_Comm_dup

    MPI_Comm_dup(MPI_COMM_WORLD, &MyWorld)
    

    創建一個新通信域MyWorld,包含於原通信域MPI_COMM_WORLD中相同的進程,但是具有不同的上下文。

  • MPI_Comm_split

    MPI_Comm_split(MyWorld, Color, Key, &SplitWorld)
    

    在通信域MyWorld的基礎上,產生幾個分割的通信域。原通信域中MyWorld中的進程按照不同的Color值處在不同的通信域中,每個進程在不同分割通信域中的編號則有Key值標識。

    Rank in MyWorld 0 1 2 3 4 5 6 7 8 9
    Color 0 1 2 0 1 2 0 1 2 0
    Key 0 0 0 1 1 1 2 2 2 3
    Rank in SplitWorld(Color=0) 0 1 2 3
    Rank in SplitWorld(Color=1) 0 1 2
    Rank in SplitWorld(Color=2) 0 1 2

2.3 組間通信

組間通信域是一種特殊的通信域,該通信域包括兩個進程組。不同進程組的進程通過組間通信域進行通信。一般把調用進程所在的進程組稱為本地進程組,而把另外一個稱為遠程進程組。

函數名 含義
MPI_Comm_test_inter 判斷給定的通信域是否為組間通信域
MPI_Comm_remote_size 獲取指定組間通信域中遠程進程組的大小
MPI_Comm_remote_group 返回給定組間通信域的遠程進程組
MPI_Intercomm_creat 根據給定的兩個組內通信域生成一個組間通信域。
MPI_Intercomm_merge 將給定組間通信域包含的兩個進程組合並,形成一個新的組內通信域

2.4 消息狀態

MPI_Status是用來存放接收消息的消息狀態,包括:

  1. 消息的原進程標識——MPI_SOURCE
  2. 消息標簽——MPI_TAG
  3. 錯誤狀態——MPI_ERROR
  4. 其他——包括數據項個數等。

假設多個客戶進程發送消息給服務進程請求服務,通過消息標簽來標識客戶進程,從而服務進程采取不同的服務,示例如下:

while (true){
    MPI_Recv(received_request,100,MPI_BYTE,MPI_Any_source,MPI_Any_tag,comm,&Status);
    switch (Status.MPI_Tag) {
        case tag_0: perform service type0;
        case tag_1: perform service type1;
        case tag_2: perform service type2;
}

2.5 點對點通信模式

MPI支持四種通信模式,同步、緩沖、標准、就緒四種。

  • 同步通信模式

    只有等相應等接收過程已經啟動,發送過程才能正確返回。

    因此,當同步發送返回時,表示發送緩沖區中的數據已經被系統緩沖區緩存,並且已經開始發送。

  • 緩沖通信模式

    緩沖通信模式的發送不管接收操作是否已經啟動都可以執行。

    但是需要用戶程序事先申請一塊足夠大的緩沖區,通過MPI_Buffer_attch實現,通過MPI_Buffer_detach來回收申請的緩沖區。

  • 標准通信模式

    是否對發送的數據進行緩沖由MPI的實現來決定,而不是由用戶程序來控制。發送是可以同步或緩沖的,取決於具體實現。

  • 就緒通信模式

    發送操作只有在接收進程相應的接收操作已經開始才進行發送。

    當發送操作啟動而相應的接收還沒有啟動,發送操作將出錯。就緒通信模式的特殊之處是接收操作必須先於發送操作啟動。

MPI同時有阻塞非阻塞兩種通信機制,它們的主要區別是返回后資源的可用性。阻塞通信的返回條件如下:

  1. 通信操作已經完成,即消息已發送或接收
  2. 調用的緩沖區可用性,若是發送操作,則該緩沖區可以被其他操作更新;若是接收操作,該緩沖區的數據已經完整,可以被正確引用。

MPI的發送支持四種通信模式,與阻塞屬性一起產生了MPI的8種發送操作,但是對於接收,只有阻塞接收和非阻塞接收兩種。

2.6 群集通信

群集通信是一個進程組中的所有進程都參加的全局通信操作,一般實現三個功能:通信、聚集和同步。通信主要完成組內數據的傳輸,聚集功能在通信的基礎上對給定的數據完成一定的操作,同步功能實現組內所有進程在執行進度上的一致性。

群集通信按照通信方向的不同,可以分為一對多通信、多對一通信和多對多通信,常見的通信函數如下:

類型 函數名 含義
通信 MPI_Bcast 一對多廣播同樣的消息
MPI_Gather 多對一收集各個進程的消息
MPI_Gatherv MPI_Gather的一般化
MPI_Allgather 全局收集
MPI_Allgatherv MPI_Allgather的一般化
MPI_Scatter 一對多散播不同的消息
MPI_Scatterv MPI_Scatter的一般化
MPI_Alltoall 多對多全局交換消息
MPI_Alltoallv MPI_Alltoall的一般化
聚集 MPI_Reduce 多對一歸約
MPI_Allreduce MPI_Reduce的一般化
MPI_Reduce_scatter MPI_Reduce的一般化
MPI_Scan 掃描
同步 MPI_Barrier 路障同步


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM