版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
十一月25MPI并行程序設(shè)計1/217參考文獻(xiàn)黃鎧,徐志偉著,陸鑫達(dá)等譯.可擴(kuò)展并行計算技術(shù),結(jié)構(gòu)與編程.
北京:機械工業(yè)出版社,P.33~56,P.227~237,2000.陳國良著.并行計算—結(jié)構(gòu)、算法、編程.北京:高等教育出版社,1999.BarryWilkinsonandMichaelAllen.ParallelProgramming(TechniquesandApplicationsusingNetworkedWorkstationsandParallelComputers).PrenticeHall,1999.李曉梅,莫則堯等著.可擴(kuò)展并行算法的設(shè)計與分析.北京:國防工業(yè)出版社,2000.張寶琳,谷同祥等著.數(shù)值并行計算原理與方法.北京:國防工業(yè)出版社,1999.都志輝著.高性能計算并行編程技術(shù)—MPI并行程序設(shè)計.北京:清華大學(xué)出版社,2001.十一月25MPI并行程序設(shè)計2/217相關(guān)網(wǎng)址MPI:,
/mpiPthreads:PVM:/pvm/
OpemMP:網(wǎng)上搜索:十一月25MPI并行程序設(shè)計3/217MPI并行程序設(shè)計ParallelProgrammingwiththeMassagePassingInterface(MPI)十一月25MPI并行程序設(shè)計4/217多線程庫標(biāo)準(zhǔn)–Win32API.–POSIXthreads.編譯制導(dǎo)標(biāo)準(zhǔn)–OpenMP–可移植共享存儲并行編程標(biāo)準(zhǔn).消息傳遞庫標(biāo)準(zhǔn)–MPI
–PVM并行編程標(biāo)準(zhǔn)本討論的重點十一月25MPI并行程序設(shè)計5/217消息傳遞并行程序設(shè)計消息傳遞并行程序設(shè)計指用戶必須通過顯式地發(fā)送和接收消息來實現(xiàn)處理機間的數(shù)據(jù)交換。在這種并行編程中,每個并行進(jìn)程均有自己獨立的地址空間,相互之間訪問不能直接進(jìn)行,必須通過顯式的消息傳遞來實現(xiàn)。這種編程方式是大規(guī)模并行處理機(MPP)和機群(Cluster)采用的主要編程方式。并行計算粒度大,特別適合于大規(guī)??蓴U(kuò)展并行算法由于消息傳遞程序設(shè)計要求用戶很好地分解問題,組織不同進(jìn)程間的數(shù)據(jù)交換,并行計算粒度大,特別適合于大規(guī)??蓴U(kuò)展并行算法.消息傳遞是當(dāng)前并行計算領(lǐng)域的一個非常重要的并行程序設(shè)計方式十一月25MPI并行程序設(shè)計6/217什么是MPI?MassagePassingInterface:是消息傳遞函數(shù)庫的標(biāo)準(zhǔn)規(guī)范,由MPI論壇開發(fā),支持Fortran和C一種新的庫描述,不是一種語言。共有上百個函數(shù)調(diào)用接口,在Fortran和C語言中可以直接對這些函數(shù)進(jìn)行調(diào)用MPI是一種標(biāo)準(zhǔn)或規(guī)范的代表,而不是特指某一個對它的具體實現(xiàn)MPI是一種消息傳遞編程模型,并成為這種編程模型的代表和事實上的標(biāo)準(zhǔn)十一月25MPI并行程序設(shè)計7/217MPI的發(fā)展過程發(fā)展的兩個階段MPI1.1:1995MPICH:是MPI最流行的非專利實現(xiàn),由Argonne國家實驗室和密西西比州立大學(xué)聯(lián)合開發(fā),具有更好的可移植性.MPI1.2~2.0:動態(tài)進(jìn)程,并行
I/O,支持F90和C++(1997).十一月25MPI并行程序設(shè)計8/217為什么要用MPI?高可移植性MPI已在IBMPC機上、MSWindows上、所有主要的Unix工作站上和所有主流的并行機上得到實現(xiàn)。使用MPI作消息傳遞的C或Fortran并行程序可不加改變地運行在IBMPC、MSWindows、Unix工作站、以及各種并行機上。十一月25MPI并行程序設(shè)計9/217講座內(nèi)容提示基本的MPI基本概念點到點通信(Pointtopoint)MPI中API的主要內(nèi)容,為MPI最基本,最重要的內(nèi)容MPI程序的編譯和運行深入MPI用戶自定義(/派生)數(shù)據(jù)類型(User-defined(Derived)datatype)事實上MPI的所有數(shù)據(jù)類型均為MPI自定義類型支持異構(gòu)系統(tǒng)允許消息來自不連續(xù)的或類型不一致的存儲區(qū)(結(jié)構(gòu),數(shù)組散元)集合通信(Collective)數(shù)據(jù)移動,數(shù)據(jù)聚集,同步基于pointtopoint構(gòu)建MPI環(huán)境管理函數(shù)組,上下文和通信空間/通信子的管理實例十一月25MPI并行程序設(shè)計10/217從簡單入手!下面我們首先分別以C語言和Fortran語言的形式給出一個最簡單的MPI并行程序Hello(下頁).該程序在終端打印出HelloWorld!字樣.“HelloWorld”:一聲來自新生兒的問候.十一月25MPI并行程序設(shè)計11/217Helloworld(C)#include<stdio.h>#include"mpi.h“main( intargc, char*argv[]){
MPI_Init(&argc,&argv);printf("Hello,world!\n");
MPI_Finalize();}十一月25MPI并行程序設(shè)計12/217Helloworld(Fortran)programmaininclude‘mpif.h’integerierrcallMPI_INIT(ierr)print*,'Hello,world!'callMPI_FINALIZE(ierr)end十一月25MPI并行程序設(shè)計13/217C和Fortran中MPI函數(shù)約定C必須包含mpi.h.MPI函數(shù)返回出錯代碼或
MPI_SUCCESS成功標(biāo)志.MPI-前綴,且只有MPI以及MPI_標(biāo)志后的第一個字母大寫,其余小寫.Fortran必須包含mpif.h.通過子函數(shù)形式調(diào)用MPI,函數(shù)最后一個參數(shù)為返回值.MPI-前綴,且函數(shù)名全部為大寫.MPI函數(shù)的參數(shù)被標(biāo)志為以下三種類型:IN:參數(shù)在例程的調(diào)用中不會被修正.OUT:參數(shù)在例程的調(diào)用中可能會被修正.INOUT:參數(shù)在一些例程中為IN,而在另一些例程中為OUT.十一月25MPI并行程序設(shè)計14/217MPI初始化-MPI_INITintMPI_Init(int*argc,char**argv)MPI_INIT(IERROR)MPI_INIT是MPI程序的第一個調(diào)用,它完成MPI程序的所有初始化工作。所有的MPI程序的第一條可執(zhí)行語句都是這條語句。啟動MPI環(huán)境,標(biāo)志并行代碼的開始.并行代碼之前,第一個mpi函數(shù)(除MPI_Initialize()外).要求main必須帶參數(shù)運行,否則出錯.十一月25MPI并行程序設(shè)計15/217MPI結(jié)束-MPI_FINALIZEintMPI_Finalize(void)MPI_FINALIZE(IERROR)MPI_FINALIZE是MPI程序的最后一個調(diào)用,它結(jié)束MPI程序的運行,它是MPI程序的最后一條可執(zhí)行語句,否則程序的運行結(jié)果是不可預(yù)知的。標(biāo)志并行代碼的結(jié)束,結(jié)束除主進(jìn)程外其它進(jìn)程.之后串行代碼仍可在主進(jìn)程(rank=0)上運行(如果必須).十一月25MPI并行程序設(shè)計16/217MPI程序的的編譯與運行mpif77hello.f或mpicchello.c默認(rèn)生成a.out的可執(zhí)行代碼.mpif77–ohellohello.f或mpicc–ohellohello.c生成hello的可執(zhí)行代碼.mpirun–np4a.outmpirun–np4hello4指定np的實參,表示進(jìn)程數(shù),由用戶指定.a.out/hello要運行的MPI并行程序.%小寫onp:Thenumberofprocess.十一月25MPI并行程序設(shè)計17/217
:運行我們的MPI程序![dair@node01~]$mpicc-ohellohello.c[dair@node01~]$./hello(
)[0]Abortingprogram!Couldnotcreatep4procgroup.Possiblemissingfileorprogramstartedwithoutmpirun.[dair@node01~]$
mpirun-np4hello
(
)HelloWorld!HelloWorld!HelloWorld!
HelloWorld![dair@node01~]$
計算機打印字符我們輸入的命令十一月25MPI并行程序設(shè)計18/217:Hello是如何被執(zhí)行的?SPMD:SingleProgramMultipleData(SPMD)
::::#include"mpi.h"#include<stdio.h>main(intargc,char*argv[]){MPI_Init(&argc,&argv);printf("Hello,world!\n");MPI_Finalize();}#include"mpi.h"#include<stdio.h>main(intargc,char*argv[]){MPI_Init(&argc,&argv);printf("Hello,world!\n");MPI_Finalize();}#include"mpi.h"#include<stdio.h>main(intargc,char*argv[]){MPI_Init(&argc,&argv);printf("Hello,world!\n");MPI_Finalize();}#include"mpi.h"#include<stdio.h>main(intargc,char*argv[]){MPI_Init(&argc,&argv);printf("Hello,world!\n");MPI_Finalize();}HelloWorld!HelloWorld!HelloWorld!HelloWorld!#include"mpi.h"#include<stdio.h>main(intargc,char*argv[]){MPI_Init(&argc,&argv);printf("Hello,world!\n");MPI_Finalize();}十一月25MPI并行程序設(shè)計19/217:開始寫MPI并行程序在寫MPI程序時,我們常需要知道以下兩個問題的答案:任務(wù)由多少個進(jìn)程來進(jìn)行并行計算?我是哪一個進(jìn)程?
十一月25MPI并行程序設(shè)計20/217:開始寫MPI并行程序MPI提供了下列函數(shù)來回答這些問題:用MPI_Comm_size
獲得進(jìn)程個數(shù)pintMPI_Comm_size(MPI_Commcomm,int*size);用MPI_Comm_rank
獲得進(jìn)程的一個叫rank的值,該
rank值為0到p-1間的整數(shù),相當(dāng)于進(jìn)程的ID intMPI_Comm_rank(MPI_Commcomm,int*rank);十一月25MPI并行程序設(shè)計21/217更新的HelloWorld(c)#include<stdio.h>#include"mpi.h"main(intargc,char*argv[]){
intmyid,
numprocs;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);printf(“Iam%dof%d\n",myid,numprocs);
MPI_Finalize();}十一月25MPI并行程序設(shè)計22/217更新的HelloWorld(Fortran)programmaininclude‘mpif.h’integerierr,myid,numprocscallMPI_INIT(ierr)callMPI_COMM_RANK(MPI_COMM_WORLD,myid,ierr)callMPI_COMM_SIZE(MPI_COMM_WORLD,numprocs,ierr)print*,‘Iam',myid,‘of',numprocscallMPI_FINALIZE(ierr)end十一月25MPI并行程序設(shè)計23/217
:運行結(jié)果[dair@node01~]$mpicc–ohello1hello1.c[dair@node01~]$mpirun-np4hello1Iam0of4Iam1of4Iam2of4Iam3of4[dair@node01~]$計算機打印字符我們輸入的命令十一月25MPI并行程序設(shè)計24/217有消息傳遞Greeting十一月25MPI并行程序設(shè)計25/217greetings(c)#include<stdio.h>#include"mpi.h"main(intargc,char*argv[]){intnumprocs,myid,source;
MPI_Statusstatus;charmessage[100];MPI_Init(&argc,&argv);MPI_Comm_rank(MPI_COMM_WORLD,&myid);MPI_Comm_size(MPI_COMM_WORLD,&numprocs);十一月25MPI并行程序設(shè)計26/217有消息傳遞greetings(c)
if(myid!=0){ strcpy(message,"HelloWorld!");
MPI_Send(message,strlen(message)+1,MPI_CHAR,0,99,MPI_COMM_WORLD);}else{/*myid==0*/for(source=1;source<numprocs;source++){MPI_Recv(message,100,MPI_CHAR,source,99,MPI_COMM_WORLD,&status);printf("%s\n",message);}}
MPI_Finalize();}/*endmain*/十一月25MPI并行程序設(shè)計27/217解剖greetings程序頭文件:mpi.h/mpif.h.intMPI_Init(int*argc,char***argv)啟動MPI環(huán)境,標(biāo)志并行代碼的開始.并行代碼之前,第一個mpi函數(shù)(除MPI_Initialize()外).要求main必須帶能運行,否則出錯.通信子(通信空間):MPI_COMM_WORLD:一個通信空間是一個進(jìn)程組和一個上下文的組合.上下文可看作為組的超級標(biāo)簽,用于區(qū)分不同的通信子.在執(zhí)行函數(shù)MPI_Init之后,一個MPI程序的所有進(jìn)程形成一個缺省的組,這個組的通信子即被寫作MPI_COMM_WORLD.該參數(shù)是MPI通信操作函數(shù)中必不可少的參數(shù),用于限定參加通信的進(jìn)程的范圍.十一月25MPI并行程序設(shè)計28/217解剖greetings程序intMPI_Comm_size(MPI_Commcomm,int*size)獲得通信空間comm中規(guī)定的組包含的進(jìn)程的數(shù)量.指定一個communicator,也指定了一組共享該空間的進(jìn)程,這些進(jìn)程組成該communicator的group.intMPI_Comm_rank(MPI_Commcomm,int*rank)得到本進(jìn)程在通信空間中的rank值,即在組中的邏輯編號(從0開始).intMPI_Finalize()標(biāo)志并行代碼的結(jié)束,結(jié)束除主進(jìn)程外其它進(jìn)程.之后串行代碼仍可在主進(jìn)程(rank=0)上運行(如果必須).十一月25MPI并行程序設(shè)計29/217消息傳送(先可不關(guān)心參數(shù)含義)MPI_Send(A,10,MPI_DOUBLE,1,99,MPI_COMM_WORLD);MPI_Recv(B,20,MPI_DOBULE,0,99,MPI_COMM_WORLD,&status);數(shù)據(jù)傳送+同步操作需要發(fā)送方與接收方合作完成.DataProcess0Process1發(fā)送請求YesDataDataDataDataDataDataDataDataTime十一月25MPI并行程序設(shè)計30/217最基本的MPIMPI調(diào)用借口的總數(shù)雖然龐大,但根據(jù)實際編寫MPI的經(jīng)驗,常用的MPI調(diào)用的個數(shù)確實有限。下面是6個最基本的MPI函數(shù)。MPI_Init(…);MPI_Comm_size(…);MPI_Comm_rank(…);MPI_Send(…);MPI_Recv(…);MPI_Finalize();MPI_Init(…);…并行代碼;…MPI_Fainalize();只能有串行代碼;十一月25MPI并行程序設(shè)計31/217講座內(nèi)容提示基本的MPI基本概念點到點通信(Pointtopoint)MPI中API的主要內(nèi)容,為MPI最基本,最重要的內(nèi)容MPI程序的編譯和運行深入MPI用戶自定義(/派生)數(shù)據(jù)類型(User-defined(Derived)datatype)事實上MPI的所有數(shù)據(jù)類型均為MPI自定義類型支持異構(gòu)系統(tǒng)允許消息來自不連續(xù)的或類型不一致的存儲區(qū)(結(jié)構(gòu),數(shù)組散元)集合通信(Collective)數(shù)據(jù)移動,數(shù)據(jù)聚集,同步基于pointtopoint構(gòu)建MPI環(huán)境管理函數(shù)組,上下文和通信空間/通信子的管理實例十一月25MPI并行程序設(shè)計32/217PointtoPoint單個進(jìn)程對單個進(jìn)程的通信,重要且復(fù)雜術(shù)語Blocking(阻塞):一個例程須等待操作完成才返回,返回后用戶可以重新使用調(diào)用中所占用的資源.
Non-blocking(非阻塞):一個例程不必等待操作完成便可返回,但這并不意味著所占用的資源可被重用.
Local(本地):不依賴于其它進(jìn)程.Non-local(非本地):依賴于其它進(jìn)程.十一月25MPI并行程序設(shè)計33/217BlockingSendintMPI_Send(void*buf,intcount,MPI_Datatypedatatype,intdest,inttag,MPI_Commcomm);
INbuf 發(fā)送緩沖區(qū)的起始地址
INcount 要發(fā)送信息的元素個數(shù)
INdatatype發(fā)送信息的數(shù)據(jù)類型
INdest 目標(biāo)進(jìn)程的rank值
INtag 消息標(biāo)簽
INcomm 通信子十一月25MPI并行程序設(shè)計34/217BlockingReceiveintMPI_Recv(void*buf,intcount,MPI_Datatypedatatype,intsource,inttag,MPI_Commcomm,MPI_Status*status);
OUTbuf 接收緩沖區(qū)的起始地址
INcount 要接收信息的元素個數(shù)
INdatatype 接收信息的數(shù)據(jù)類型
INsource
源進(jìn)程的rank值
INtag 消息標(biāo)簽
INcomm 通信子
OUTstatus status對象,包含實際接收到的消息的有關(guān)信息十一月25MPI并行程序設(shè)計35/217MPI消息MPI消息包括信封和數(shù)據(jù)兩個部分,信封指出了發(fā)送或接收消息的對象及相關(guān)信息,而數(shù)據(jù)是本消息將要傳遞的內(nèi)容數(shù)據(jù):<起始地址、數(shù)據(jù)個數(shù)、數(shù)據(jù)類型>信封:<源/目的、標(biāo)識、通信域>十一月25MPI并行程序設(shè)計36/217消息數(shù)據(jù)由count個類型為datatype的連續(xù)數(shù)據(jù)空間組成,起始地址為buf不是以字節(jié)數(shù),而是以元素的個數(shù)指定消息的長度count可以是零,這種情況下消息的數(shù)據(jù)部分是空的MPI基本數(shù)據(jù)類型相應(yīng)于宿主語言的基本數(shù)據(jù)類型十一月25MPI并行程序設(shè)計37/217什么是緩沖區(qū)?應(yīng)用程序中說明的變量,在消息傳遞語句中又用作緩沖區(qū)的起始位置.也可表示由系統(tǒng)(不同用戶)創(chuàng)建和管理的某一存儲區(qū)域,在消息傳遞過程中用于暫存放消息.也被稱為系統(tǒng)緩沖區(qū).用戶可設(shè)置一定大小的存儲區(qū)域,用作中間緩沖區(qū)以保留可能出現(xiàn)在其應(yīng)用程序中的任意消息.進(jìn)程PAM進(jìn)程QB進(jìn)程PAMS進(jìn)程QB進(jìn)程PAMT進(jìn)程QB系統(tǒng)緩沖區(qū)用戶指定緩沖區(qū)用戶緩沖區(qū)十一月25MPI并行程序設(shè)計38/217MPI標(biāo)識一條消息的信息包含四個域:Source:發(fā)送進(jìn)程隱式確定,由進(jìn)程的rank值唯一標(biāo)識Destination:Send函數(shù)參數(shù)確定Tag:Send函數(shù)參數(shù)確定,用于識別不同的消息
(0,UB),UB:MPI_TAG_UB>=32767.Communicator:缺省MPI_COMM_WORLDGroup:有限/N,有序/Rank[0,1,2,…N-1]Contex:Super_tag,用于標(biāo)識該通訊空間.消息信封十一月25MPI并行程序設(shè)計39/217十一月25MPI并行程序設(shè)計40/217消息匹配接收buffer必須至少可以容納count個由datatype參數(shù)指明類型的數(shù)據(jù).如果接收buf太小,將導(dǎo)致溢出、出錯.消息匹配參數(shù)匹配dest,tag,comm/source,tag,commSource==MPI_ANY_SOURCE:接收任意處理器來的數(shù)據(jù)(任意消息來源).Tag==MPI_ANY_TAG:匹配任意tag值的消息(任意tag消息).在阻塞式消息傳送中不允許Source==Dest,否則會導(dǎo)致deadlock.消息傳送被限制在同一個communicator.在send函數(shù)中必須指定唯一的接收者(Push/pull通訊機制).十一月25MPI并行程序設(shè)計41/217status參數(shù)當(dāng)使用MPI_ANY_SOURCE或/和MPI_ANY_TAG接收消息時如何確定消息的來源source和tag值呢?在C中,status.MPI_SOURCE,status.MPI_TAG.在Fortran中,source=status(MPI_SOURCE),tag=status(MPI_TAG).Status還可用于返回實際接收到消息的長度intMPI_Get_count(MPI_Statusstatus,MPI_Datatypedatatype,int*count)INstatus接收操作的返回值.INdatatype接收緩沖區(qū)中元素的數(shù)據(jù)類型.OUTcount接收消息中的元素個數(shù).十一月25MPI并行程序設(shè)計42/217分析greetings#include<stdio.h>#include"mpi.h“main(intargc,char*argv[]){ intnumprocs;/*進(jìn)程數(shù),該變量為各處理器中的同名變量,存儲是分布的 */ intmyid; /*我的進(jìn)程ID,存儲也是分布的 */ MPI_Statusstatus; /*消息接收狀態(tài)變量,存儲也是分布的 */
charmessage[100]; /*消息buffer,存儲也是分布的 */
/*初始化MPI*/
MPI_Init(&argc,&argv);/*該函數(shù)被各進(jìn)程各調(diào)用一次,得到自己的進(jìn)程rank值*/
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
/*該函數(shù)被各進(jìn)程各調(diào)用一次,得到進(jìn)程數(shù)*/
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);十一月25MPI并行程序設(shè)計43/217分析greetingsif(myid!=0){
/*建立消息*/sprintf(message,"Greetingsfromprocess%d!",myid);
/*發(fā)送長度取strlen(message)+1,使\0也一同發(fā)送出去*/
MPI_Send(message,strlen(message)+1,MPI_CHAR,0,99,MPI_COMM_WORLD);}else{/*my_rank==0*/for(source=1;source<numprocs;source++){MPI_Recv(message,100,MPI_CHAR,source,99,MPI_COMM_WORLD,&status);printf(“%s\n",message);}}
/*關(guān)閉MPI,標(biāo)志并行代碼段的結(jié)束*/
MPI_Finalize();}/*Endmain*/十一月25MPI并行程序設(shè)計44/217Greetings執(zhí)行過程
假設(shè)進(jìn)程數(shù)為3(進(jìn)程0)(進(jìn)程1)(進(jìn)程2)(rank=0)(rank=1)(rank=2)..Recv();..Recv();.....Send();......Send()...問題:進(jìn)程1和2誰先向根進(jìn)程發(fā)送消息??%十一月25MPI并行程序設(shè)計45/217運行g(shù)reetings[dair@node01~]$mpicc–ogreetinggreeting.c[dair@node01~]$mpirun-np4greetingGreetingsfromprocess1!Greetingsfromprocess2!Greetingsfromprocess3![dair@node01~]$計算機打印字符我們輸入的命令十一月25MPI并行程序設(shè)計46/217現(xiàn)在您已經(jīng)能夠用MPI進(jìn)行并行編程了!十一月25MPI并行程序設(shè)計47/217避免死鎖deadlock發(fā)送和接收是成對出現(xiàn)的,忽略這個原則很可能會產(chǎn)生死鎖總會死鎖的通信調(diào)用次序十一月25MPI并行程序設(shè)計48/217不安全的通信調(diào)用次序十一月25MPI并行程序設(shè)計49/217安全的通信調(diào)用次序十一月25MPI并行程序設(shè)計50/217MPI_Sendrecv函數(shù)原型int
MPI_Sendrecv(
void *sendbuf,
int sendcount,
MPI_Datatypesendtype,
int dest,
int sendtag,
void *recvbuf,
int recvcount,
MPI_Datatyperecvtype,
int source,
int recvtag,
MPI_Commcomm,
MPI_Status*status)數(shù)據(jù)輪換p0p1p2P(n-1)pi十一月25MPI并行程序設(shè)計51/217MPI_Sendrecv用法示意…inta,b;…MPI_Statusstatus;intdest=(rank+1)%p;intsource=(rank+p-1)%p;/*p為進(jìn)程個數(shù)*/MPI_Sendrecv(&a,1,MPI_INT,dest,99,&b1,MPI_INT,source,99,MPI_COMM_WORLD,&status);該函數(shù)被每一進(jìn)程執(zhí)行一次.十一月25MPI并行程序設(shè)計52/217空進(jìn)程rank=MPI_PROC_NULL的進(jìn)程稱為空進(jìn)程使用空進(jìn)程的通信不做任何操作.向MPI_PROC_NULL發(fā)送的操作總是成功并立即返回.從MPI_PROC_NULL接收的操作總是成功并立即返回,且接收緩沖區(qū)內(nèi)容為隨機數(shù).statusstatus.MPI_SOURCE=MPI_PROC_NULLstatus.MPI_TAG=MPI_ANY_TAGMPI_Get_count(&status,MPI_Datatypedatatype,&count)=>count=0p0p1p2P(n-1)pi空進(jìn)程十一月25MPI并行程序設(shè)計53/217空進(jìn)程應(yīng)用示意…MPI_Statusstatus;intdest=(rank+1)%p;intsource=(rank+p-1)%p;if(source==p-1)source=MPI_PROC_NULL;if(dest==0)dest=MPI_PROC_NULL;MPI_Sendrecv(&a,1,MPI_INT,dest,99,&b1,MPI_INT,source,99,MPI_COMM_WORLD,&status);…十一月25MPI并行程序設(shè)計54/217阻塞與非阻塞的差別用戶發(fā)送緩沖區(qū)的重用:非阻塞的發(fā)送:僅當(dāng)調(diào)用了有關(guān)結(jié)束該發(fā)送的語句后才能重用發(fā)送緩沖區(qū),否則將導(dǎo)致錯誤;對于接收方,與此相同,僅當(dāng)確認(rèn)該接收請求已完成后才能使用。所以對于非阻塞操作,要先調(diào)用等待MPI_Wait()或測試MPI_Test()函數(shù)來結(jié)束或判斷該請求,然后再向緩沖區(qū)中寫入新內(nèi)容或讀取新內(nèi)容。阻塞發(fā)送將發(fā)生阻塞,直到通訊完成.非阻塞可將通訊交由后臺處理,通信與計算可重疊.發(fā)送語句的前綴由MPI_改為MPI_I,I:immediate:標(biāo)準(zhǔn)模式:MPI_Send(…)->MPI_Isend(…)Buffer模式:MPI_Bsend(…)->MPI_Ibsend(…)…十一月25MPI并行程序設(shè)計55/217非阻塞發(fā)送與接收intMPI_Isend(void*buf,intcount,MPI_Datatypedatatype,intdest,inttag,MPI_Commcomm,MPI_Request*request)INbuf發(fā)送緩沖區(qū)的起始地址INcount發(fā)送緩沖區(qū)的大小(發(fā)送元素個數(shù))INdatatype發(fā)送緩沖區(qū)數(shù)據(jù)的數(shù)據(jù)類型INdest目的進(jìn)程的秩INtag消息標(biāo)簽INcomm通信空間/通信子OUTrequest非阻塞通信完成對象(句柄)intMPI_Irecv(void*buf,intcount,MPI_Datatypedatatype,intsource,inttag,MPI_Commcomm,MPI_Request*request)十一月25MPI并行程序設(shè)計56/217非阻塞標(biāo)準(zhǔn)發(fā)送和接收十一月25MPI并行程序設(shè)計57/217通信的完成(常用于非阻塞通信)發(fā)送的完成:代表發(fā)送緩沖區(qū)中的數(shù)據(jù)已送出,發(fā)送緩沖區(qū)可以重用。它并不代表數(shù)據(jù)已被接收方接收。數(shù)據(jù)有可能被緩沖;接收的完成:代表數(shù)據(jù)已經(jīng)寫入接收緩沖區(qū)。接收者可訪問接收緩沖區(qū)。通過MPI_Wait()和MPI_Test()來判斷通信是否已經(jīng)完成;十一月25MPI并行程序設(shè)計58/217MPI_Wait()及應(yīng)用示例intMPI_Wait(MPI_Request*request,MPI_Status*status);當(dāng)request標(biāo)識的通信結(jié)束后,MPI_Wait()才返回。如果通信是非阻塞的,返回時request=MPI_REQUEST_NULL;函數(shù)調(diào)用是非本地的;MPI_Requestrequest;MPI_Statusstatus;intx,y;if(rank==0){MPI_Isend(&x,1,MPI_INT,1,99,comm,&request)…MPI_Wait(&request,&status);}else{MPI_Irecv(&y,1,MPI_INT,0,99,comm,&request)…MPI_Wait(&request,&status);}十一月25MPI并行程序設(shè)計59/217MPI_Test()及應(yīng)用示例//intMPI_Test(MPI_Request*request,int*flag,MPI_Status*status);MPI_Requestrequest;MPI_Statusstatus;intx,y,flag;if(rank==0){MPI_Isend(&x,1,MPI_INT,1,99,comm,&request)while(!flag)MPI_Test(&request,&flag,&status);}else{MPI_Irecv(&y,1,MPI_INT,0,99,comm,&request)while(!flag)MPI_Test(&request,&flag,&status);}十一月25MPI并行程序設(shè)計60/217消息探測
--Probe函數(shù)(適用于阻塞與非阻塞)MPI_Probe()和MPI_Iprobe()函數(shù)探測接收消息的內(nèi)容。用戶根據(jù)探測到的消息內(nèi)容決定如何接收這些消息,如根據(jù)消息大小分配緩沖區(qū)等。前者為阻塞方式,即只有探測到匹配的消息才返回;后者為非阻塞,即無論探測到與否均立即返回.intMPI_Probe(intsource,inttag,MPI_Commcomm,MPI_Status*status)intMPI_Iprobe(intsource,inttag,MPI_Commcomm,int*flag,MPI_Status*status)INsource數(shù)據(jù)源的rank,可以是MPI_ANY_SOURCEINtag數(shù)據(jù)標(biāo)簽,可以是MPI_ANY_TAGINcomm通信空間/通信子OUTflag布爾值,表示探測到與否(只用于非阻塞方式)OUTstatusstatus對象,包含探測到消息的內(nèi)容十一月25MPI并行程序設(shè)計61/217MPI_Probe應(yīng)用示例intx;floaty;MPI_Comm_rank(comm,&rank);if(rank==0)/*0->2發(fā)送一int型數(shù)*/MPI_Send(100,1,MPI_INT,2,99,comm);elseif(rank==1)/*1->2發(fā)送一float型數(shù)*/MPI_Send(100.0,1,MPI_FLOAT,2,99,comm);else
/*根進(jìn)程接收*/for(inti=0;i<2;i++){MPI_Probe(MPI_ANY_SOURCE,0,comm,&status);/*Blocking*/if(status.MPI_SOURCE==0)MPI_Recv(&x,1,MPI_INT,0,99,&status);elseif(status.MPI_SOURCE==1)MPI_Recv(&y,1,MPI_FLOAT,0,99,&status);}十一月25MPI并行程序設(shè)計62/217講座內(nèi)容提示基本的MPI基本概念點到點通信(Pointtopoint)MPI中API的主要內(nèi)容,為MPI最基本,最重要的內(nèi)容MPI程序的編譯和運行深入MPI用戶自定義(/派生)數(shù)據(jù)類型(User-defined(Derived)datatype)事實上MPI的所有數(shù)據(jù)類型均為MPI自定義類型支持異構(gòu)系統(tǒng)允許消息來自不連續(xù)的或類型不一致的存儲區(qū)(結(jié)構(gòu),數(shù)組散元)集合通信(Collective)數(shù)據(jù)移動,數(shù)據(jù)聚集,同步基于pointtopoint構(gòu)建MPI環(huán)境管理函數(shù)組,上下文和通信空間/通信子的管理實例十一月25MPI并行程序設(shè)計63/217MPI程序的編譯mpicc編譯并連接用C語言編寫的MPI程序mpiCC編譯并連接用C++編寫的MPI程序mpif77編譯并連接用FORTRAN77編寫的MPI程序mpif90編譯并連接用Fortran90編寫的MPI程序這些命令可以自動提供MPI需要的庫,并提供特定的開關(guān)選項(用-help查看)。十一月25MPI并行程序設(shè)計64/217MPI程序的編譯用mpicc編譯時,就像用一般的C編譯器一樣。還可以使用一般的C的編譯選項,含義和原來的編譯器相同例如:./mpicc-cfoo.c./mpicc-ofoofoo.o十一月25MPI并行程序設(shè)計65/217MPI程序的運行MPI程序的執(zhí)行步驟一般為:編譯以得到MPI可執(zhí)行程序(若在同構(gòu)的系統(tǒng)上,只需編譯一次;若系統(tǒng)異構(gòu),則要在每一個異構(gòu)系統(tǒng)上都對MPI源程序進(jìn)行編譯)將可執(zhí)行程序拷貝到各個節(jié)點機上通過mpirun命令并行執(zhí)行MPI程序十一月25MPI并行程序設(shè)計66/217最簡單的MPI運行命令mpirun–npN<program>其中:N:同時運行的進(jìn)程數(shù)<program>:可執(zhí)行MPI程序名例如:mpirun–np6cpimpirun–np4hello十一月25MPI并行程序設(shè)計67/217一種靈活的執(zhí)行方式mpirun–p4pg<pgfile><program><pgfile>為配置文件,其格式為:<機器名><進(jìn)程數(shù)><程序名><機器名><進(jìn)程數(shù)><程序名><機器名><進(jìn)程數(shù)><程序名>例如:(注:第一行的0并不表示在node0上沒有進(jìn)程,這里的0特指在node0上啟動MPI程序)node00/public0/dair/mpi/cpinode11/public0/dair/mpi/cpinode21/public0/dair/mpi/cpi這種方式允許可執(zhí)行程序由不同的名字和不同的路徑十一月25MPI并行程序設(shè)計68/217另一種靈活的執(zhí)行方式mpirun–machinefile<machinefile>-np<N><program><machinefile>為配置文件,其格式為:<機器名><機器名><機器名>例如:node0node1node2node3十一月25MPI并行程序設(shè)計69/217完整的MPI運行方式MPI程序的一般啟動方式:mpirun–np<numberofprocessor><programnameandargument>完整的MPI運行方式:mpirun[mpirun_options]<program>[options…]詳細(xì)參數(shù)信息執(zhí)行mpirun-help十一月25MPI并行程序設(shè)計70/217講座內(nèi)容提示基本的MPI基本概念點到點通信(Pointtopoint)MPI中API的主要內(nèi)容,為MPI最基本,最重要的內(nèi)容MPI程序的編譯和運行深入MPI用戶自定義(/派生)數(shù)據(jù)類型(User-defined(Derived)datatype)事實上MPI的所有數(shù)據(jù)類型均為MPI自定義類型支持異構(gòu)系統(tǒng)允許消息來自不連續(xù)的或類型不一致的存儲區(qū)(結(jié)構(gòu),數(shù)組散元)集合通信(Collective)數(shù)據(jù)移動,數(shù)據(jù)聚集,同步基于pointtopoint構(gòu)建MPI環(huán)境管理函數(shù)組,上下文和通信空間/通信子的管理實例十一月25MPI并行程序設(shè)計71/217MPI數(shù)據(jù)類型……if(my_rank!=0){
/*建立消息*/sprintf(message,"Greetingsfromprocess%d!",my_rank);
/*發(fā)送長度取strlen(message)+1,使\0也一同發(fā)送出去*/
MPI_Send(message,strlen(message)+1,MPI_CHAR,0,99,MPI_COMM_WORLD);}else{/*my_rank==0*/for(source=1;source<p;source++){MPI_Recv(message,100,MPI_CHAR,source,99,MPI_COMM_WORLD,&status);printf(“%s\n",message);}}
/*關(guān)閉MPI,標(biāo)志并行代碼段的結(jié)束*/
MPI_Finalize();}/*main*/十一月25MPI并行程序設(shè)計72/217用戶自定義數(shù)據(jù)類型/派生數(shù)據(jù)類型目的異構(gòu)計算:不同系統(tǒng)有不同的數(shù)據(jù)表示格式。MPI預(yù)先定義一些基本數(shù)據(jù)類型,在實現(xiàn)過程中在這些基本數(shù)據(jù)類型為橋梁進(jìn)行轉(zhuǎn)換。派生數(shù)據(jù)類型:允許消息來自不連續(xù)的和類型不一致的存儲區(qū)域,如數(shù)組散元與結(jié)構(gòu)類型等的傳送。MPI中所有數(shù)據(jù)類型均為MPI自定義類型基本數(shù)據(jù)類型,如MPI_INT,MPI_DOUBLE…用戶定義數(shù)據(jù)類型或派生數(shù)據(jù)類型.十一月25MPI并行程序設(shè)計73/217MPI基本數(shù)據(jù)類型十一月25MPI并行程序設(shè)計74/217數(shù)據(jù)類型圖十一月25MPI并行程序設(shè)計75/217DerivedDatatype(派生)常用MPI_Type_contiguousMPI_Type_vectorMPI_Type_indexedMPI_Type_struct十一月25MPI并行程序設(shè)計76/217MPI_Type_contiguous將原數(shù)據(jù)類型,按順序進(jìn)行多次復(fù)制十一月25MPI并行程序設(shè)計77/217在FORTRAN中定義矩陣的一列REALA(1000,1000)INTEGERF_COLMPI_TYPE_CONTIGUOUS(1000,MPI_REAL,F_COL)MPI_SEND(A,1,F_COL,right,tag,MPI_COMM_WORLD)在C中定義矩陣的一行floata[1000][1000];MPI_DatatypeC_R;MPI_Type_contiguous(1000,MPI_FLOAT,&C_R);MPI_SEND(&(a[0][0]),1,C_R,right,tag,MPI_COMM_WORLD)十一月25MPI并行程序設(shè)計78/217用MPI_Vector進(jìn)行矩陣的行列置換以C語言的數(shù)組表示為例:將矩陣的一列送到另一數(shù)組的一行中十一月25MPI并行程序設(shè)計79/217MPI_Vector函數(shù)原型MPI_Vector()函數(shù)首先通過連續(xù)復(fù)制若干個舊數(shù)據(jù)類型形成一個“塊”,然后通過等間隔地復(fù)制該塊兒形成新的數(shù)據(jù)類型。塊與塊之間的空間時舊數(shù)據(jù)類型的倍數(shù)。#include"mpi.h"intMPI_Type_vector( intcount, /*數(shù)據(jù)塊個數(shù)
(非負(fù)整數(shù))*/
intblocklen, /*塊中元素個數(shù)
(非負(fù)整數(shù))*/
intstride, /*塊間起始地址間隔
(非負(fù)整數(shù))*/
MPI_Datatypeold_type, /*原始數(shù)據(jù)類型(句柄)*/
MPI_Datatype*newtype /*派生數(shù)據(jù)類型指針*/)十一月25MPI并行程序設(shè)計80/217MPI_Type_vector應(yīng)用示意
用MPI_Vector進(jìn)行矩陣的行列置換
…
floatA[10][10];
MPI_Datatypecolumn_mpi_t;
MPI_Type_vector(10,1,10,MPI_FLOAT,&column_mpi_t);
MPI_Type_commit(&column_mpi_t);
if(my_rank==0)
MPI_Send(&(A[0][0]),1,column_mpi_t,1,0,MPI_COMM_WORLD);
else{/*my_rank=1*/
MPI_Recv(&(A[0][0]),10,MPI_FLOAT,0,0,MPI_COMM_WORLD,&status);…十一月25MPI并行程序設(shè)計81/217用MPI_Type_indexed發(fā)送矩陣的上三角部分以C語言表示的數(shù)組為例,數(shù)組按行連續(xù)存儲十一月25MPI并行程序設(shè)計82/217MPI_Type_indexed函數(shù)原型#include"mpi.h" intMPI_Type_indexed( intcount, /*數(shù)據(jù)塊的個數(shù),數(shù)據(jù)塊間不連續(xù)*/
intblocklens[],/*每一數(shù)據(jù)塊中元素的個數(shù),為一個非負(fù)整型數(shù)組*/
intindices[], /*每一塊數(shù)據(jù)在原始數(shù)據(jù)類型中的起始位置,整型數(shù)組*/
MPI_Datatypeold_type, /*原始數(shù)據(jù)類型(名柄)*/
MPI_Datatype*newtype /*派生數(shù)據(jù)類型指針*/)十一月25MPI并行程序設(shè)計83/217MPI_Type_indexed應(yīng)用示意(將A矩陣的上三角部分送到另一個處理器中的T矩陣的對應(yīng)位置)
float A[n][n];/*CompleteMatrix*/float T[n][n]; /*UpperTriangle*/int displacements[n];int block_lengths[n];MPI_Datatypeindex_mpi_t;
for(i=0;i<n;i++){block_lengths[i]=n-i;displacements[i]=(n+1)*i;}MPI_Type_indexed(n,block_lengths,displacements,MPI_FLOAT,&index_mpi_t);MPI_Type_commit(&index_mpi_t);
if(my_rank==0)
MPI_Send(A,1,index_mpi_t,1,0,MPI_COMM_WORLD);else
/*my_rank==1*/
MPI_Recv(T,1,index_mpi_t,0,0,MPI_COMM_WORLD,&status);十一月25MPI并行程序設(shè)計84/217MPI_Type_struct允許每個塊包含不同數(shù)據(jù)類型的拷貝十一月25MPI并行程序設(shè)計85/217MPI_Type_struct的例子structpartstruct{charclass;doubled[6];charb[7]};structpartstructparticle[1000];inti,dest,rank;MPI_Datatypeparticletype,type[3]={MPI_CHAR,MPI_DOUBLE,MPI_CHAR}intblocklen[3]={1,6,7};MPI_Aintdisp[3]={0,sizeof(double),7*sizeof(double)};MPI_Type_struct(3,blocklen,disp,type,&particletype);十一月25MPI并行程序設(shè)計86/217其它派生類型MPI_HvectorMPI_HindexedMPI_Pack/MPI_Unpack:數(shù)據(jù)打包/解包是其它數(shù)據(jù)派生數(shù)據(jù)類型的基礎(chǔ),MPI不建議用戶進(jìn)行顯式的數(shù)據(jù)打包為了與早期其它并行庫兼容十一月25MPI并行程序設(shè)計87/217MPI_Pack()intMPI_Pack( void *inbuf, /*輸入緩沖區(qū)起始地址*/ int incount, /*輸入數(shù)據(jù)項個數(shù)*/ MPI_Datatype datatype,/*輸入數(shù)據(jù)項的數(shù)據(jù)類型*/ void *outbuf, /*輸出緩沖區(qū)起始地址*/ int outcount, /*輸出緩沖區(qū)大小*/ int *position, /*輸出緩沖區(qū)當(dāng)前位置*/ MPI_Comm comm/*通信域*/)例:packsize=0;MPI_Pack(&a,1,MPI_INT,packbuf,100,&packsize,MPI_COMM_WORLD);MPI_Pack(&b,1,MPI_DOUBLE,packbuf,100,&packsize,MPI_COMM_WORLD);十一月25MPI并行程序設(shè)計88/217MPI_Unpack()intMPI_Unpack( void *inbuf, /*輸入緩沖區(qū)起始地址*/ int incount, /*輸入數(shù)據(jù)項大小*/ int *position, /*緩沖區(qū)當(dāng)前位置*/ void *outbuf, /*輸出緩沖區(qū)起始地址*/ int outcount, /*輸出緩沖區(qū)大小*/ MPI_Datatype datatype,/*輸出數(shù)據(jù)項的數(shù)據(jù)類型*/ MPI_Comm comm/*通信域*/)例:pos=0;MPI_Unpack(packbuf,packsize,&pos,&a,1,MPI_INT,MPI_COMM_WROLD);MPI_Unpack(packbuf,packsize,&pos,&b,1,MPI_FLOAT,MPI_COMM_WROLD);十一月25MPI并行程序設(shè)計89/217派生數(shù)據(jù)類型的應(yīng)用提交:intMPI_Type_commit(MPIDatatype*datatype)將數(shù)據(jù)類型映射進(jìn)行轉(zhuǎn)換或“編譯”一種數(shù)據(jù)類型變量可反復(fù)定義,連續(xù)提交釋放:intMPI_Typefree(MPI_Datatype*datatype)將數(shù)據(jù)類型設(shè)為MPI_DATATYPE_NULL十一月25MPI并行程序設(shè)計90/217講座內(nèi)容提示基本的MPI基本概念點到點通信(Pointtopoint)MPI中API的主要內(nèi)容,為MPI最基本,最重要的內(nèi)容MPI程序的編譯和運行深入MPI用戶自定義(/派生)數(shù)據(jù)類型(User-defined(Derived)datatype)事實上MPI的所有數(shù)據(jù)類型均為MPI自定義類型支持異構(gòu)系統(tǒng)允許消息來自不連續(xù)的或類型不一致的存儲區(qū)(結(jié)構(gòu),數(shù)組散元)集合通信(Collective)數(shù)據(jù)移動,數(shù)據(jù)聚集,同步基于pointtopoint構(gòu)建MPI環(huán)境管理函數(shù)組,上下文和通信空間/通信子的管理實例十一月25MPI并行程序設(shè)計91/217集合通信
CollectiveCommunication特點通信空間中的所有進(jìn)程都參與通信操作每一個進(jìn)程都需要調(diào)用該操作函數(shù)一到多多到一同步十一月25MPI并行程序設(shè)計92/217類型函數(shù)功能數(shù)據(jù)移動MPI_Bcast一到多,數(shù)據(jù)廣播MPI_Gather多到一,數(shù)據(jù)匯合MPI_GathervMPI_Gather的一般形式MPI_AllgatherMPI_Gather的一般形式MPI_AllgathervMPI_Allgather的一般形式MPI_Scatter一到多,數(shù)據(jù)分散MPI_ScattervMPI_Scatter的一般形式MPI_Alltoall多到多,置換數(shù)據(jù)(全互換)MPI_AlltoallvMPI_Alltoall的一般形式數(shù)據(jù)聚集MPI_Reduce多到一,數(shù)據(jù)歸約MPI_Allreduce上者的一般形式,結(jié)果在所有進(jìn)程MPI_Reduce_scatter結(jié)果scatter到各個進(jìn)程MPI_Scan前綴操作同步MPI_Barrier同步操作MPI集合通信函數(shù)All:表示結(jié)果到所有進(jìn)程.V:Variety,被操作的數(shù)據(jù)對象和操作更為靈活.%十一月25MPI并行程序設(shè)計93/217數(shù)據(jù)移動
Broadcast
Scatter
Gather
Allgather
Alltoall十一月25MPI并行程序設(shè)計94/217數(shù)據(jù)聚集ReduceAllreduceReduce-scatterScanMPI預(yù)定義全局?jǐn)?shù)據(jù)運算符:MPI_MAX/MPI_MIN;MPI_SUM求和MPI_PROD求積MPI_LAND邏輯與MPI_LOR邏輯或MPI_MAXLOC/MPI_MINLOC最大/小值求下相應(yīng)位置…
…十一月25MPI并行程序設(shè)計95/217intp,myrank;floatbuf;MPI_Commcomm;MPI_Init(&argc,&argv);/*得進(jìn)程編號*/MPI_Comm_rank(comm,&my_rank);/*得進(jìn)程總數(shù)*/MPI_Comm_size(comm,&p);if(myrank==0) buf=1.0;MPI_Bcast(&buf,1,MPI_FLOAT,0,comm);Broadcast--數(shù)據(jù)廣播databuf..MPI_Bcast();.data..MPI_Bcast();.data..MPI_Bcast();.Process0myrank=0Process1myrank=1Processp-1myrank=p-1intMPI_Bcast( void*buffer,/*發(fā)送/接收buf*/ intcount, /*元素個數(shù)*/ MPI_Datatypedatatype,
introot, /*指定根進(jìn)程*/ MPI_Commcomm)根進(jìn)程既是發(fā)送緩沖區(qū)也是接收緩沖區(qū)十一月25MPI并行程序設(shè)計96/217Gather--數(shù)據(jù)收集intp,myrank;floatdata[10];/*分布變量*/float*buf;MPI_Commcomm;MPI_Init(&argc,&argv);/*得進(jìn)程編號*/MPI_Comm_rank(comm,&my_rank);/*得進(jìn)程總數(shù)*/MPI_Comm_size(comm,&p);if(myrank==0) buf=(float*)malloc(p*10*sizeof(float);/*開辟接收緩沖區(qū)*/MPI_Gather(data,10,MPI_FLOAT, buf,10,MPI_FlOAT,0,comm);data.MPI_Gather();.data.MPI_Gather();.data.MPI_Gather();.Process0myrank=0Process1myrank=1Processp-1myrank=p-1根進(jìn)程接收其他進(jìn)程來的消息(包括根進(jìn)程),按每在進(jìn)程在通信組中的編號依次聯(lián)接在一下,存放在根進(jìn)程的接收緩沖區(qū)中.intMPI_Gather(void*sendbuf,intsendcnt,MPI_Datatypesendtype,void*recvbuf,intrecvcount,MPI_Datatyperecvtype,introot,MPI_Commcomm)buf十一月25MPI并行程序設(shè)計97/217Scatter--數(shù)據(jù)分散intp,myrank;floatdata[10];float*buf;MPI_Commcomm;MPI_Init(&argc,&argv);/*得進(jìn)程編號*/MPI_Comm_rank(comm,&my_rank);/*得進(jìn)程總數(shù)*/MPI_Comm_size(comm,&p);if(myrank==0) buf=(float*)malloc(p*10*sizeof(float);/*開辟發(fā)送緩沖區(qū)*/MPI_Scatter(buf,10,MPI_FLOAT, data,10,MPI_FlOAT,0,comm);data.MPI_Scatter();.data.MPI_Scatter();.data.MPI_Scatter();.P
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 醫(yī)院行政科招聘面試題及參考解析
- 國電投煤炭開發(fā)部總經(jīng)理競聘考試題庫含答案
- 工程師-面試題及答案
- 2025年智慧消防管理系統(tǒng)項目可行性研究報告
- 2025年3D打印產(chǎn)業(yè)鏈完善項目可行性研究報告
- 2025年醫(yī)療大數(shù)據(jù)分析平臺開發(fā)項目可行性研究報告
- 2025年創(chuàng)意產(chǎn)業(yè)園區(qū)開發(fā)可行性研究報告
- 2025年短視頻平臺變現(xiàn)模式創(chuàng)新可行性研究報告
- 2025年非洲市場投資開發(fā)項目可行性研究報告
- 虛擬現(xiàn)實 游戲的新風(fēng)口
- 醫(yī)務(wù)人員職業(yè)道德準(zhǔn)則(2025年版)全文培訓(xùn)課件
- 2025年大學(xué)試題(法學(xué))-著作權(quán)法歷年參考題庫含答案解析(5套典型題)
- 神經(jīng)外科飲食健康宣教
- 《構(gòu)成設(shè)計基礎(chǔ)》全套教學(xué)課件
- 學(xué)堂在線 雨課堂 學(xué)堂云 海上求生與救生 期末考試答案
- 裝配式建筑施工重點難點及標(biāo)準(zhǔn)化措施
- 山東省高二物理會考20252025年真題
- 高級英語2 (第四版)張漢熙 練習(xí)答案
- 非遺文化創(chuàng)意園項目可行性研究報告申請報告編制
- Unit1CulturalHeritageReadingforWriting課件-高一英語人教版
- 幼兒園健康教育活動設(shè)計與實施知到課后答案智慧樹章節(jié)測試答案2025年春漢中職業(yè)技術(shù)學(xué)院
評論
0/150
提交評論