MPI编程及性能优化
第1節(jié) MPI簡介
1.1 MPI及其歷史
與OpenMP相似,消息傳遞接口(Message Passing Interface,簡稱MPI)是一種編程接口標準,而不是一種具體的編程語言。該標準是由消息傳遞接口論壇(Message Passing Interface Forum,簡稱MPIF)發(fā)起討論并進行規(guī)范化的。
MPI標準從1992年開始起草,1994年發(fā)布第一個版本MPI-1(MPI v1.0,進而發(fā)展出1.1和1.2版),到1997年發(fā)布第二個版本MPI-2(MPI v2.0)。MPI標準如今已經(jīng)成為事實意義上的消息傳遞并行編程標準,也是最為流行的并行編程接口。
由于MPI提供了統(tǒng)一的接口,該標準受到各種并行平臺上的廣泛支持,這也使得MPI程序具有良好的可移植性。目前,MPI支持多種編程語言,包括Fortran77,Fortran90以及C/C++;同時,MPI支持多種操作系統(tǒng),包括大多數(shù)的類UNIX系統(tǒng)以及Windows系統(tǒng)(Windows 2000、Windows XP等);MPI還支持多核(Multicore)、對稱多處理機(SMP)、集群(Cluster)等各種硬件平臺。。
1.2?典型MPI實現(xiàn)簡介
1.MPICH
MPICH是影響最大、用戶最多的MPI實現(xiàn)。
MPICH的特點在于:
??????? 開放源碼;
??????? 與MPI標準同步發(fā)展;
??????? 支持多程序多數(shù)據(jù)(Multiple Program Multiple Data,MPMD)編程和異構集群系統(tǒng);
??????? 支持C/C++、Fortran 77 和Fortran 90的綁定;對Fortran的支持提供了頭文件mpif.h和模塊兩種方式;
??????? 支持類Unix和Windows NT平臺;
??????? 支持環(huán)境非常廣泛,包括多核、SMP、集群和大規(guī)模并行計算系統(tǒng);
除此之外,MPICH軟件包中還集成了并行程序設計環(huán)境組件,包括并行性能可視化分析工具和性能測試工具等。
2.Intel MPI
Intel MPI是由Intel公司推出的符合MPI-2標準的MPI實現(xiàn)。其最新版本是3.0版,突出的特色在于提供了靈活的多架構支持。
Intel MPI提供了名為Direct Access Programming Library (DAPL)的中間層來支持多架構,兼容多種網(wǎng)絡硬件及協(xié)議,優(yōu)化網(wǎng)絡互聯(lián)。Intel MPI庫及DAPL互聯(lián)結構可用圖7.1.1清晰地表示出來。
圖7.1 Intel MPI庫及其基于 DAPL 的互聯(lián)結構
從圖7.1可以看出,Intel MPI透明地支持TCP/IP、共享內存,并基于DAPL有效支持多種高性能互聯(lián)系統(tǒng), Intel MPI提供更好的線程安全機制,多線程的MPI程序并不限制MPI的使用。
1.3 MPI程序特點
MPI程序是基于消息傳遞的并行程序。消息傳遞指的是并行執(zhí)行的各個進程具有自己獨立的堆棧和代碼段,作為互不相關的多個程序獨立執(zhí)行,進程之間的信息交互完全通過顯式地調用通信函數(shù)來完成。
基于消息傳遞的并行程序可以劃分為單程序多數(shù)據(jù)(Single Program Multiple Data,簡稱SPMD)和多程序多數(shù)據(jù)MPMD兩種形式。SPMD使用一個程序來處理多個不同的數(shù)據(jù)集以達到并行的目的。并行執(zhí)行的不同程序實例處于完全對等的位置。相應的,MPMD程序使用不同的程序處理多個數(shù)據(jù)集,合作求解同一個問題。
SPMD是MPI程序中最常用的并行模型。圖7.2為SPMD執(zhí)行模型的示意圖,其中表示了一個典型的SPMD程序,同樣的程序prog_a運行在不同的處理核上,處理了不同的數(shù)據(jù)集。
圖 7.2 SPMD執(zhí)行模型
| ? | |
| ? |
圖7.5則給出了三種典型MPMD程序的執(zhí)行模型。
(a)是一個管理者(Master)/工人(Worker)類型的MPMD程序
(b)為另外一種類型的MPMD程序:聯(lián)合數(shù)據(jù)分析程序。在大部分的時間內,不同的程序各自獨立的完成自己的任務,并在特定的時候交換數(shù)據(jù)。
(c)是流式的MPMD程序,程序運行由prog_a、prog_b和prog_c組成,這三個程序的執(zhí)行過程就好像工廠里的流水線一樣。
| ? | |
| ? |
圖 7.5 MPMD執(zhí)行模型
通過學習本小節(jié)介紹的MPI程序的特點,以及SPMD和MPMD的多種執(zhí)行模型,讀者就可以在以后的開發(fā)過程中靈活地設計不同的MPI并行程序。
PI-2提出的高級功能將在第7.6節(jié)中將做簡要說明。
第2節(jié) MPI編程基礎
2.1?簡單的MPI程序示例
首先,我們來看一個簡單的MPI程序實例。如同我們學習各種語言的第一個程序一樣,對于MPI的第一個程序同樣是"Hello Word"。
/* Case 1 hellow.c */
#include <stdio.h>
#include "mpi.h"
int main( int argc, char *argv[] ) {
int rank;
int size;
??? MPI_Init( argc, argv?);
??? MPI_Comm_rank(MPI_COMM_WORLD, &rank);
??? MPI_Comm_size(MPI_COMM_WORLD, &size);
??? printf( "Hello world from process %d of %d\n", rank, size );
??? MPI_Finalize();
??? return 0;
}
根據(jù)上一節(jié)的介紹,我們使用如下命令編譯和鏈接這個程序:
mpicc –o hellow hellow.c
運行這個例子可以在可執(zhí)行文件的目錄中執(zhí)行mpiexec –np 4 ./hellow。運行結果如下:
Hello world from process 0 of 4
Hello world from process 1 of 4
Hello world from process 2 of 4
Hello world from process 3 of 4
這個程序在MPI程序運行的每個進程中分別打印各自的MPI進程號(0~3)和總進程數(shù)(4)。
?????? 值得注意的是,由于四個進程是并行執(zhí)行,所以即使輸出的順序有變化也是正常的,程序中并沒有限制哪個進程在前,哪個進程在后。
2.2 MPI程序的四個基本函數(shù)
1.MPI_Init和MPI_Finalize
MPI_Init用來初始化MPI執(zhí)行環(huán)境,建立多個MPI進程之間的聯(lián)系,為后續(xù)通信做準備。而MPI_Finalize則是結束MPI執(zhí)行環(huán)境。
如同OpenMP定義并行區(qū)一樣,這兩個函數(shù)就是用來定義MPI程序的并行區(qū)的。也就是說,除了檢測是否初始化的函數(shù)之外,不應該在這兩個函數(shù)定義的區(qū)域之外調用其他MPI函數(shù)。
2.MPI_Comm_rank
第7.1節(jié)介紹過SPMD的程序形式,給出的例子中需要通過進程標識和總數(shù)來分配數(shù)據(jù)。MPI_Comm_rank就是來標識各個MPI進程的,告訴調用該函數(shù)的進程“我是誰?”。MPI_Comm_rank返回整型的錯誤值,需要提供兩個函數(shù)參數(shù):
???????? MPI_Comm類型的通信域,標識參與計算的MPI進程組。
???????? 整型指針,返回進程在相應進程組中的進程號。進程號從0開始編號。
3.MPI_Comm_size
本函數(shù)則用來標識相應進程組中有多少個進程。
2.3 MPI的點對點通信
點對點通信是MPI編程的基礎。本節(jié)我們將重點介紹其中兩個最重要的MPI函數(shù)MPI_Send和MPI_Recv。
| int MPI_SEND(buf, count, datatype, dest, tag, comm); |
輸入?yún)?shù)包括:
???????? buf,發(fā)送緩沖區(qū)的起始地址,可以是各種數(shù)組或結構的指針。
???????? count,整型,發(fā)送的數(shù)據(jù)個數(shù),應為非負整數(shù)。
???????? datatype,發(fā)送數(shù)據(jù)的數(shù)據(jù)類型,這個參數(shù)將在后續(xù)節(jié)中詳細介紹。
???????? dest,整型,目的進程號。
???????? tag,整型,消息標志,后續(xù)節(jié)中會做進一步介紹。
???????? comm,MPI進程組所在的通信域,留待后續(xù)節(jié)進一步介紹。
該函數(shù)沒有輸出參數(shù),返回錯誤碼。
這個函數(shù)的含義是向通信域comm中的dest進程發(fā)送數(shù)據(jù)。消息數(shù)據(jù)存放在buf中,類型是datatype,個數(shù)是count個。這個消息的標志是tag,用以和本進程向同一目的進程發(fā)送的其它消息區(qū)別開來。
| int MPI_RECV(buf,count,datatype,source,tag,comm,status); |
n???????? status,MPI_Status結構指針,返回狀態(tài)信息。
MPI_Status的結構定義在mpi.h當中可以找到。
| /* The order of these elements must match that in mpif.h */ typedef struct MPI_Status { ??? int count; ??? int cancelled; ??? int MPI_SOURCE; ??? int MPI_TAG; ??? int MPI_ERROR; } MPI_Status; |
?
| int MPI_Get_count(?MPI_Status *status, MPI_Datatype datatype, int *count); |
??????? count,是實際接收到的給定數(shù)據(jù)類型的數(shù)據(jù)項數(shù)
2.4?消息管理7要素
MPI最重要的功能莫過于消息傳遞。正如我們先前看到一樣,MPI_Send和MPI_Recv負責在兩個進程間發(fā)送和接收消息。總結起來,點對點消息通信的參數(shù)主要是由以下7個參數(shù)組成:
(1)??? 發(fā)送或者接收緩沖區(qū)buf;
(2)??? 數(shù)據(jù)數(shù)量count;
(3)??? 數(shù)據(jù)類型datatype;
(4)??? 目標進程或者源進程destination/source;
(5)??? 消息標簽tag;
(6)??? 通信域comm;.
(7)??? 消息狀態(tài)status,只在接收的函數(shù)中出現(xiàn)。
1.消息數(shù)據(jù)類型
在消息緩沖的三個變量中,最值得注意的是datatype,消息數(shù)據(jù)類型。
為什么需要定義消息數(shù)據(jù)類型?主要的理由有兩個:一是支持異構平臺計算的互操作性,二是允許方便地將非連續(xù)內存區(qū)中的數(shù)據(jù),具有不同數(shù)據(jù)類型的內容組成消息。MPI程序有嚴格的數(shù)據(jù)類型匹配要求。類型匹配包涵了兩個層面的內容:一是宿主語言的類型(C或者Fortran數(shù)據(jù)類型)和通信操作所指定的類型相匹配;二是發(fā)送方和接收方的類型匹配。MPI用預定義的基本數(shù)據(jù)類型和導出數(shù)據(jù)類型來滿足上述要求。
(1)????基本數(shù)據(jù)類型
如前所述,我們需要發(fā)送和接收連續(xù)的數(shù)據(jù),MPI提供了預定義的數(shù)據(jù)類型供程序員使用。
表7.3.1 MPI預定義數(shù)據(jù)類型與C數(shù)據(jù)類型的對應關系
| MPI預定義數(shù)據(jù)類型 | 相應的C數(shù)據(jù)類型 |
| MPI_CHAR | signed char |
| MPI_SHORT | signed short int |
| MPI_INT | signed int |
| MPI_LONG | signed long int |
| MPI_UNSIGNED_CHAR | unsigned char |
| MPI_UNSIGNED_SHORT | unsigned short int |
| MPI_UNSIGNED | unsigned int |
| MPI_UNSIGNED_LONG | unsigned long int |
| MPI_FLOAT | float |
| MPI_DOUBLE | double |
| MPI_LONG_DOUBLE | long double |
| MPI_BYTE | 無對應類型 |
| MPI_PACKED | 無對應類型 |
對于初學者來說,應盡可能保證發(fā)送和接收的數(shù)據(jù)類型完全一致。
(2)????導出數(shù)據(jù)類型
除了這些基本數(shù)據(jù)類型之外,MPI還允許通過導出數(shù)據(jù)類型,將不連續(xù)的,甚至是不同類型的數(shù)據(jù)元素組合在一起形成新的數(shù)據(jù)類型。我們稱這種由用戶定義的數(shù)據(jù)類型為導出數(shù)據(jù)類型。
歸納起來類型匹配規(guī)則可以概括為:
??????? 有類型數(shù)據(jù)的通信,發(fā)送方和接收方均使用相同的數(shù)據(jù)類型;
??????? 無類型數(shù)據(jù)的通信,發(fā)送方和接收方均以MPI_BYTE作為數(shù)據(jù)類型;
??????? 打包數(shù)據(jù)的通信,發(fā)送方和接收方均使用MPI_PACKED。
2.?通信域
一個通信域(comm)包含一個進程組(process group)及其上下文(context)。進程組是進程的有限有序集。通信域限定了消息傳遞的進程范圍。
MPI實現(xiàn)已經(jīng)預先定義了兩個進程組:MPI_COMM_SELF,只包含各個進程自己的進程組;MPI_COMM_WORLD,包含本次啟動的所有MPI進程的進程組。同時,MPI還為通信子提供了各種管理函數(shù),其中包括:
(1)??? 通信域比較int MPI_Comm_compare(comm1, comm2, result):如comm1,comm2為相同句柄,則result為MPI_Ident;如果僅僅是各進程組的成員和序列號都相同,則result為MPI_Congruent;如果二者的組成員相同但序號不同則結果為MPI_Similar;否則,結果為MPI_Unequal。
(2)??? 通信域拷貝int MPI_Comm_dup(comm, newcom):對comm進行復制得到新的通信域newcomm。
(3)??? 通信域分裂int MPI_Comm_split(comm, color, key, newcomm):本函數(shù)要求comm進程組中的每個進程都要執(zhí)行,每個進程指定一個color(整型),此調用首先將具有相同color值的進程形成一個新的進程組,新產(chǎn)生的通信域與這些進程組一一對應。新通信域中各個進程的順序編號根據(jù)key(整型)的大小決定,即key越小,則相應進程在新通信域中的順序編號也越小,若一個進程中的key相同,則根據(jù)這兩個進程在原來通信域中順序號決定新的進程號。一個進程可能提供color值為MPI_Undefined,此種情況下,其newcomm返回MPI_COMM_NULL。
(4)??? 通信域銷毀int MPI_Comm_free(comm):釋放給定通信域。
上述函數(shù)都返回錯誤碼。
?
2.5?統(tǒng)計時間
MPI提供了兩個時間函數(shù)MPI_Wtime和MPI_Wtick。其中,MPI_Wtime函數(shù)返回一個雙精度數(shù),標識從過去的某點的時間到當前時間所消耗的時間秒數(shù)。而函數(shù)MPI_Wtick則返回MPI_Wtime結果的精度。
2.6?錯誤管理
MPI在錯誤管理方面提供了豐富的接口函數(shù),這里我們介紹其中最簡單的部分接口。
n???????? 用status.MPI_ERROR來獲取錯誤碼。
n???????? MPI終止MPI程序執(zhí)行的函數(shù)MPI_Abort。
| int MPI_Abort(MPI_Comm comm, int errorcode) |
它使comm通信域的所有進程退出,返回errorcode給調用的環(huán)境。通信域comm中的任一進程調用此函數(shù)都能夠使該通信域內所有的進程結束運行。
第3節(jié) MPI群集通信
除了前面介紹的點到點通信之外,MPI還提供了群集通信。所謂群集通信,包含了一對多,多對一和多對多的進程通信模式。它的最大的特點就是多個進程參與通信,下面我們將要介紹在MPI中常用的幾個群集通信函數(shù)。
3.1?同步
本函數(shù)接口是:int MPI_Barrier(MPI_Comm comm)。
這個函數(shù)像一道路障。在操作中,通信子comm中的所有進程相互同步,即它們相互等待,直到所有進程都執(zhí)行了他們各自的MPI_Barrier函數(shù),然后再各自接著開始執(zhí)行后續(xù)的代碼。同步函數(shù)是并行程序中控制執(zhí)行順序的有效手段。
3.2?廣播
廣播顧名思義,就是一對多的傳送消息。它的作用是從一個root進程向組內所有其他的進程發(fā)送一條消息。它的接口形式是:
int MPI_Bcast( void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm )
圖7.13給出了廣播操作的示意。
圖7.13?廣播操作示意圖圖
3.3?聚集
聚集函數(shù)MPI_Gather是一個多對一的通信函數(shù)。其接口為:
int MPI_Gather(void *sendbuf, int sendcnt, MPI_Datatype sendtype,
?? ??????????void *recvbuf, int recvcnt, MPI_Datatype recvtype,
???????????? int root, MPI_Comm comm)
root進程接收該通信組每一個成員進程(包括root自已)發(fā)送的消息。這n個消息的連接按進程號排列存放在root進程的接收緩沖中。每個發(fā)送緩沖由三元組(sendbuf, sendcnt, sendtype)標識。所有非root進程忽略接收緩沖,對root進程發(fā)送緩沖由三元組(recvbuf, recvcnt, recvtype)標識。圖7.14給出聚集操作的示意。
| ? |
圖7.14?聚集操作示意圖
3.4?播撒
int MPI_Scatter(void *sendbuf, int sendcnt, MPI_Datatype sendtype,
???????????? void *recvbuf, int recvcnt, MPI_Datatype recvtype, int root,
???????????? MPI_Comm comm)
播撒函數(shù)MPI_Scatter是一對多的傳遞消息。但是它和廣播不同,root進程向各個進程傳遞的消息是可以不同的。Scatter實際上執(zhí)行的是與Gather相反的操作。
3.5擴展的聚集和播撒操作
MPI_Allgather的作用是每一個進程都收集到其他所有進程的消息,它相當于每一個進程都執(zhí)行了MPI_Gather執(zhí)行完了MPI_Gather之后,所有的進程的接收緩沖區(qū)的內容都是相同的,也就是說每個進程給所有進程都發(fā)送了一個相同的消息,所以名為allgather。本函數(shù)的接口是:
int MPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
?????????????? void *recvbuf, int recvcount, MPI_Datatype recvtype,
?????????????? MPI_Comm comm)
圖7.15給出了擴展的聚集和播撒操作的示意。
圖7.15?擴展的聚集和播撒操作示意圖
3.6全局交換
MPI_Allgather每個進程發(fā)一個相同的消息給所有的進程,而MPI_Alltoall散發(fā)給不同進程的消息是不同的。因此,它的發(fā)送緩沖區(qū)也是一個數(shù)組。MPI_Alltoall的每個進程可以向每個接收者發(fā)送數(shù)目不同的數(shù)據(jù),第i個進程發(fā)送的第j塊數(shù)據(jù)將被第j個進程接收并存放在其接收消息緩沖區(qū)recvbuf的第i塊,每個進程的sendcount和sendtype的類型必須和所有其他進程的recvcount和recvtype相同,這也意謂著在每個進程和根進程之間發(fā)送的數(shù)據(jù)量必須和接收的數(shù)據(jù)量相等。函數(shù)接口為:
int MPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype,
????????????? void *recvbuf, int recvcount, MPI_Datatype recvtype,
????????????? MPI_Comm comm)
全局交換的操作示意圖為圖7.4.4。
圖7.4.4?全局交換操作示意圖
3.7規(guī)約與掃描
MPI提供了兩種類型的聚合操作:歸約(reduction)和掃描(scan)。
1.歸約
int MPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype,
????????????? MPI_Op op, int root, MPI_Comm comm)
這里每個進程的待處理數(shù)據(jù)存放在sendbuf中,可以是標量也可以是向量。所有進程將這些值通過輸入的操作子op計算為最終結果并將它存入root進程的recvbuf。數(shù)據(jù)項的數(shù)據(jù)類型在Datatype域中定義。具體的歸約操作包括:
???????? MPI_MAX 求最大值
???????? MPI_MIN 求最小值
???????? MPI_SUM 求和
???????? MPI_PROD 求積
???????? MPI_LAND 邏輯與
???????? MPI_BAND 按位與
???????? MPI_LOR 邏輯或
???????? MPI_BOR 按位或
???????? MPI_LXOR 邏輯異或
???????? MPI_BXOR 按位異或
???????? MPI_MAXLOC 最大值且相應位置
???????? MPI_MINLOC 最小值且相應位置
規(guī)約操作的數(shù)據(jù)類型組合如表7.4.1所示。
表7.4.1 規(guī)約操作與相應類型的對應關系
| 操作 | 允許的數(shù)據(jù)類型 |
| MPI_MAX,MPI_MIN | C整數(shù),Fortran整數(shù),浮點數(shù) |
| MPI_SUM,MPI_PROD | C整數(shù),Fortran整數(shù),浮點數(shù),復數(shù) |
| MPI_LAND,MPI_LOR,MPI_XLOR | C整數(shù),邏輯型 |
| MPI_BAND,MPI_BOR,MPI_BXOR | C整數(shù),Fortran整數(shù),字節(jié)型 |
?
在MPI中,針對規(guī)約操作,所有的MPI預定義的操作都是可結合的,也是可交換的。同時,用戶可以指定自定義的函數(shù)操作,這些操作是也要可結合的,但可以不是可交換的。
2.掃描
int MPI_Scan(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype,
??????????? MPI_Op op, MPI_Comm comm)
MPI_Scan常用于對分布于組中的數(shù)據(jù)作前置歸約操作。此操作將序列號為0,···,i(包括i)的進程發(fā)送緩沖區(qū)的歸約結果存入序列號為i?的進程接收消息緩沖區(qū)中。這種操作支持的數(shù)據(jù)類型、操作以及對發(fā)送及接收緩沖區(qū)的限制和規(guī)約相同。與規(guī)約相比,掃描Scan操作省去了Root域,因為掃描是將部分值組合成n個最終值,并存放在n個進程的recvbuf中。具體的掃描操作由Op域定義。
MPI的歸約和掃描操作允許每個進程貢獻向量值,而不只是標量值。向量的長度由Count定義。MPI也支持用戶自定義的歸約操作。
第4節(jié) MPI性能分析與優(yōu)化舉例
4.1?選取計算粒度
當通信的成為并行程序性能瓶頸的時候,一般來說選取較高的計算粒度可以降低進程間的通信開銷。例如,用7個進程完成A、B、C 3個不相關的任務,如果B的計算量為A的2倍,而C的計算量為A的4倍。
一種并行執(zhí)行的策略是采用任務內并行的方式,如圖7.16(a)所示,這種方案中對于每一個任務都在7個進程上并行執(zhí)行,所以每執(zhí)行一個任務需要進行一次數(shù)據(jù)分配,和一次數(shù)據(jù)收集。而采用任務間并行的模式,即更大粒度的并行分配方式,只需要一次數(shù)據(jù)分配和一次數(shù)據(jù)收集,節(jié)約了兩次集合通信(如圖7.16(b)所示)。
?
|
4.2聚合消息
一種減少通信次數(shù)的方法就是將小的消息聚合起來一次發(fā)送,這種優(yōu)化稱為消息聚合。如果零碎的消息很多,則通過消息聚合可以得到很大的性能提高。
4.3解決負載均衡問題
在并行計算中,如果各個處理器(核)上的工作需要的完成時間不同,則會使先完成的處理器等待未完成的處理器(核),浪費了計算資源。若這種情況如果比較嚴重,就應該采用策略來使各處理器負載盡量平衡。一般采用的策略有兩種,一種為靜態(tài)負載平衡,一種為動態(tài)負載平衡。前者適用于計算前可以準確知道總的負載,而且這些負載容易平均劃分給各個進程的情況。而對于事先不知道負載總數(shù),或者總負載不易平均劃分的情況,則可能需要采用動態(tài)負載劃分來解決。
稠密的矩陣與向量乘法運算是一個靜態(tài)負載平衡的例子,假設矩陣為N×M階,而有p個相同處理器可以用于計算,按行分解每個處理器分得或行,若干按列分解每個處理器分得或列,如圖7.19所示。當然還可以按矩形塊分解矩陣,這時要根據(jù)具體矩形塊的大小進行。
動態(tài)負載平衡我們采用三角矩陣與向量的乘法為例。存在一個管理節(jié)點,將矩陣未完成的行發(fā)送給工作節(jié)點,當工作節(jié)點完成任務后主動向管理節(jié)點索要任務,當管理節(jié)點上沒有未完成任務時,向所有進程發(fā)送終止信號,如圖7.20所示。這是通過主從模式,有效維護任務池,實現(xiàn)動態(tài)負載平衡的例子。
圖7.19 矩陣向量乘靜態(tài)負載平衡示意圖
圖7.20? 動態(tài)負載平衡示意圖
from:?http://jpck.zju.edu.cn/eln/200805131515180671/page.jsp?cosid=1423&JSPFILE=page&LISTFILE=list&CHAPFILE=listchapter&PATH=200805131515180671&ROOTID=6380&NODEID=6403&DOCID=8717
總結
以上是生活随笔為你收集整理的MPI编程及性能优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用MFC制作程序启动logo
- 下一篇: Windows系统下搭建MPI环境