MPI編程入門詳解

MPI簡介

說到并行計(jì)算往弓,我們有一個(gè)不可繞開的話題——MPI編程态兴。MPI是一個(gè)跨語言的通訊協(xié)議浙炼,用于編寫并行計(jì)算機(jī)份氧。支持點(diǎn)對(duì)點(diǎn)和廣播。MPI是一個(gè)信息傳遞應(yīng)用程序接口弯屈,包括協(xié)議和和語義說明,他們指明其如何在各種實(shí)現(xiàn)中發(fā)揮其特性恋拷。MPI的目標(biāo)是高性能资厉,大規(guī)模性,和可移植性蔬顾。MPI在今天仍為高性能計(jì)算的主要模型宴偿。與OpenMP并行程序不同,MPI是一種基于信息傳遞的并行編程技術(shù)诀豁。消息傳遞接口是一種編程接口標(biāo)準(zhǔn)窄刘,而不是一種具體的編程語言。簡而言之舷胜,MPI標(biāo)準(zhǔn)定義了一組具有可移植性的編程接口娩践。
筆者在上一篇文章《如何在win10+vs2013上配置MPI并行編程環(huán)境》中詳細(xì)介紹了如何在win10環(huán)境下配置MPI環(huán)境,還沒有配置編程環(huán)境的小伙伴建議查看這邊文章烹骨,以便于以后的學(xué)習(xí)(畢竟并行機(jī)不是你想擁有就能擁有的)翻伺。

MPI基本函數(shù)

MPI調(diào)用借口的總數(shù)雖然龐大, 但根據(jù)實(shí)際編寫MPI的經(jīng)驗(yàn)沮焕, 常用的MPI調(diào)用的個(gè)數(shù)確什么有限吨岭。 下面是6個(gè)最基本的MPI函數(shù)。
1.? MPI_Init(…);
2.? MPI_Comm_size(…);
3.? MPI_Comm_rank(…);
4.? MPI_Send(…);
5.? MPI_Recv(…);
6.? MPI_Finalize();
我們?cè)诖送ㄟ^一個(gè)簡單的例子來說明這6個(gè)MPI函數(shù)的基本用處峦树。

函數(shù)介紹

1. int MPI_Init (int* argc ,char** argv[] )

該函數(shù)通常應(yīng)該是第一個(gè)被調(diào)用的MPI函數(shù)用于并行環(huán)境初始化辣辫,其后面的代碼到 MPI_Finalize()函數(shù)之前的代碼在每個(gè)進(jìn)程中都會(huì)被執(zhí)行一次。
–? 除MPI_Initialized()外魁巩, 其余所有的MPI函數(shù)應(yīng)該在其后被調(diào)用急灭。
–? MPI系統(tǒng)將通過argc,argv得到命令行參數(shù)(也就是說main函數(shù)必須帶參數(shù),否則會(huì)出錯(cuò))歪赢。

2. int MPI_Finalize (void)

–? 退出MPI系統(tǒng)化戳, 所有進(jìn)程正常退出都必須調(diào)用。 表明并行代碼的結(jié)束,結(jié)束除主進(jìn)程外其它進(jìn)程。
–? 串行代碼仍可在主進(jìn)程(rank = 0)上運(yùn)行点楼, 但不能再有MPI函數(shù)(包括MPI_Init())扫尖。

3. int MPI_Comm_size (MPI_Comm comm ,int* size )

–? 獲得進(jìn)程個(gè)數(shù) size。
–? 指定一個(gè)通信子,也指定了一組共享該空間的進(jìn)程, 這些進(jìn)程組成該通信子的group(組)掠廓。
–? 獲得通信子comm中規(guī)定的group包含的進(jìn)程的數(shù)量换怖。

4. int MPI_Comm_rank (MPI_Comm comm ,int* rank)

–? 得到本進(jìn)程在通信空間中的rank值,即在組中的邏輯編號(hào)(該 rank值為0到p-1間的整數(shù),相當(dāng)于進(jìn)程的ID。)

5. int MPI_Send( void *buff, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)

–void *buff:你要發(fā)送的變量蟀瞧。
–int count:你發(fā)送的消息的個(gè)數(shù)(注意:不是長度沉颂,例如你要發(fā)送一個(gè)int整數(shù),這里就填寫1悦污,如要是發(fā)送“hello”字符串铸屉,這里就填寫6(C語言中字符串未有一個(gè)結(jié)束符,需要多一位))切端。
–MPI_Datatype datatype:你要發(fā)送的數(shù)據(jù)類型彻坛,這里需要用MPI定義的數(shù)據(jù)類型,可在網(wǎng)上找到踏枣,在此不再羅列昌屉。
–int dest:目的地進(jìn)程號(hào),你要發(fā)送給哪個(gè)進(jìn)程茵瀑,就填寫目的進(jìn)程的進(jìn)程號(hào)间驮。
–int tag:消息標(biāo)簽,接收方需要有相同的消息標(biāo)簽才能接收該消息马昨。
–MPI_Comm comm:通訊域竞帽。表示你要向哪個(gè)組發(fā)送消息。


參數(shù)說明

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

–void *buff:你接收到的消息要保存到哪個(gè)變量里偏陪。
–int count:你接收消息的消息的個(gè)數(shù)(注意:不是長度抢呆,例如你要發(fā)送一個(gè)int整數(shù),這里就填寫1笛谦,如要是發(fā)送“hello”字符串抱虐,這里就填寫6(C語言中字符串未有一個(gè)結(jié)束符,需要多一位))饥脑。它是接收數(shù)據(jù)長度的上界. 具體接收到的數(shù)據(jù)長度可通過調(diào)用MPI_Get_count 函數(shù)得到恳邀。
–MPI_Datatype datatype:你要接收的數(shù)據(jù)類型,這里需要用MPI定義的數(shù)據(jù)類型灶轰,可在網(wǎng)上找到谣沸,在此不再羅列。
–int dest:接收端進(jìn)程號(hào)笋颤,你要需要哪個(gè)進(jìn)程接收消息就填寫接收進(jìn)程的進(jìn)程號(hào)乳附。
–int tag:消息標(biāo)簽内地,需要與發(fā)送方的tag值相同的消息標(biāo)簽才能接收該消息。
–MPI_Comm comm:通訊域赋除。
–MPI_Status *status:消息狀態(tài)阱缓。接收函數(shù)返回時(shí),將在這個(gè)參數(shù)指示的變量中存放實(shí)際接收消息的狀態(tài)信息举农,包括消息的源進(jìn)程標(biāo)識(shí)荆针,消息標(biāo)簽,包含的數(shù)據(jù)項(xiàng)個(gè)數(shù)等颁糟。

示例

基本函數(shù)都已經(jīng)介紹完航背,現(xiàn)在我們來用一個(gè)示例來加強(qiáng)對(duì)這些基本函數(shù)的理解。

#include <stdio.h>
#include <string.h>
#include "mpi.h"
void main(int argc, char* argv[])
{
    int numprocs, myid, source;
    MPI_Status status;
    char message[100];
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &myid);
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
    if (myid != 0) {  //非0號(hào)進(jìn)程發(fā)送消息
        strcpy(message, "Hello World!");
        MPI_Send(message, strlen(message) + 1, MPI_CHAR, 0, 99,
            MPI_COMM_WORLD);
    }
    else {   // myid == 0棱貌,即0號(hào)進(jìn)程接收消息
        for (source = 1; source < numprocs; source++) {
            MPI_Recv(message, 100, MPI_CHAR, source, 99,
                MPI_COMM_WORLD, &status);
            printf("接收到第%d號(hào)進(jìn)程發(fā)送的消息:%s\n", source, message);
        }
    }
    MPI_Finalize();
} /* end main */

運(yùn)行結(jié)果如下圖所示


執(zhí)行結(jié)果

可以看到玖媚,當(dāng)筆者開啟四線程運(yùn)行時(shí),1-3號(hào)進(jìn)程發(fā)送消息婚脱,0號(hào)進(jìn)程接收到消息并打幼钪选;當(dāng)筆者開啟八線程運(yùn)行時(shí)起惕,1-7號(hào)進(jìn)程發(fā)送消息,0號(hào)進(jìn)程接收到消息并打印咏删。


消息發(fā)送示意

本文使用的是標(biāo)準(zhǔn)阻塞接收發(fā)送的方式惹想。消息傳遞是MPI的特性,也是我們學(xué)習(xí)的難點(diǎn)督函。這我們學(xué)習(xí)MPI必須掌握的嘀粱。

消息發(fā)送與接收函數(shù)的參數(shù)的一些重要說明。

1.MPI標(biāo)識(shí)一條消息的信息包含四個(gè)域:

–? 源:發(fā)送進(jìn)程隱式確定,進(jìn)程rank值唯一標(biāo)識(shí).
–? 目的:Send函數(shù)參數(shù)確定.
–? Tag:Send函數(shù)參數(shù)確定, (0,UB) 232-1.
–? 通信子:缺省MPI_COMM_WORLD
?? Group:有限/N辰狡, 有序/Rank [0,1,2,…N-1]
?? Contex:Super_tag,用于標(biāo)識(shí)該通訊空間.

2. buffer的使用

buffer必須至少可以容納count個(gè)由datatype指明類型的數(shù)據(jù). 如果接收buf太小, 將導(dǎo)致溢出锋叨、 出錯(cuò)

3. 消息匹配

–? 參數(shù)匹配source,tag,comm/dest,tag,comm.
–? Source == MPI_ANY_SOURCE: 接收任意處理器來的數(shù)據(jù)(任意消息來源).
–? Tag == MPI_ANY_TAG: 匹配任意tag值的消息(任意tag消息).

4. 在阻塞式消息傳送中不允許Source == dest,否則會(huì)導(dǎo)致死鎖.

5. 消息傳送被限制在同一個(gè)通信域內(nèi)。

6. 在send函數(shù)中必須指定唯一的接收者宛篇。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末娃磺,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子叫倍,更是在濱河造成了極大的恐慌偷卧,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吆倦,死亡現(xiàn)場離奇詭異听诸,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蚕泽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門晌梨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事仔蝌》毫欤” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵掌逛,是天一觀的道長师逸。 經(jīng)常有香客問我,道長豆混,這世上最難降的妖魔是什么篓像? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮皿伺,結(jié)果婚禮上员辩,老公的妹妹穿的比我還像新娘。我一直安慰自己鸵鸥,他們只是感情好奠滑,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著妒穴,像睡著了一般宋税。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上讼油,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天杰赛,我揣著相機(jī)與錄音,去河邊找鬼矮台。 笑死乏屯,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的瘦赫。 我是一名探鬼主播辰晕,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼确虱!你這毒婦竟也來了含友?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤蝉娜,失蹤者是張志新(化名)和其女友劉穎唱较,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體召川,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡南缓,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了荧呐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片汉形。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纸镊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出概疆,到底是詐尸還是另有隱情逗威,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布岔冀,位于F島的核電站凯旭,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏使套。R本人自食惡果不足惜罐呼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望侦高。 院中可真熱鬧嫉柴,春花似錦、人聲如沸奉呛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瞧壮。三九已至登馒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咆槽,已是汗流浹背谊娇。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留罗晕,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓赠堵,卻偏偏與公主長得像小渊,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子茫叭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容