C02高级MPI编程技术.ppt

上传人:仙人指路1688 文档编号:2904356 上传时间:2023-03-02 格式:PPT 页数:188 大小:1.78MB
返回 下载 相关 举报
C02高级MPI编程技术.ppt_第1页
第1页 / 共188页
C02高级MPI编程技术.ppt_第2页
第2页 / 共188页
C02高级MPI编程技术.ppt_第3页
第3页 / 共188页
C02高级MPI编程技术.ppt_第4页
第4页 / 共188页
C02高级MPI编程技术.ppt_第5页
第5页 / 共188页
点击查看更多>>
资源描述

《C02高级MPI编程技术.ppt》由会员分享,可在线阅读,更多相关《C02高级MPI编程技术.ppt(188页珍藏版)》请在三一办公上搜索。

1、高级MPI编程技术,谭光明 副研究员中国科学院计算技术研究所国家智能计算机研究开发中心计算机体系结构国家重点实验室(筹),阻塞通信模式,由发送方体现(send语句).阻塞通信中接收语句相同按发送方式的不同,消息或直接被copy到接收者的buffer中或被拷贝到系统buffer中。标准模式Standard最常用的发送方式B:缓冲模式Buffer发到系统缓冲区S:同步模式Synchronous任意发出,不需系统缓冲区R:就绪模式Ready就绪发出,不需系统缓冲区,阻塞,需要等待操作的实际完成,或至少等待MPI系统安全地备份后才返回;MPI_Send与MPI_Recv都是阻塞的;MPI_Send调用

2、返回时表明数据已经发出或被MPI系统复制,随后对发送缓冲区的修改不会改变所发送的数据;而MPI_Recv返回,则表明已完成数据接收。函数调用是非局部的,测量点到点通信带宽(p2p),#include#include#include“mpi.h”int main(int argc,char*argv)intmy_rank,tag=0,send_m,recv_m;charmessage100,send_c100,recv_c100;floatsend_n,recv_n;double start_time,end_time;MPI_Status status;MPI_Commcomm;MPI_Ini

3、t(,测量点到点通信带宽(p2p),start_time=MPI_Wtime();MPI_Send(,测量点到点通信带宽(p2p),else/*my_rank=1*/MPI_Recv(,测量点到点通信带宽(hot_potato),#include“mpi.h”main(int argc,char*argv)intp,my_rank,tag,source,dest,tag=0;MPI_Status status;char send_m100,recv_m100;doublestart_time,end_time;MPI_Commcomm;MPI_Init(/*消息接收的源*/,测量点到点通信带宽

4、,if(my_rank=0)sprintf(send_m,Greetings from process%d!,my_rank);/*建立消息*/start_time=MPI_Wtime()MPI_Send(send_m,strlen(send_m)+1,MPI_CHAR,dest,tag,comm);MPI_Recv(recv_m,100,MPI_CHAR,source,tag,comm,/*关闭MPI,标志并行代码段的结束*/*main*/,接收的有序性,在阻塞通信中对于接收进程在接收消息时除了要求接收到的消息的消息信封和接收操作自身的消息信封相一致还要求它接收到的消息是最早发送给自己的消息

5、若两个消息的消息信封都和自己的消息信封吻合则必须先接收首先发送的消息哪怕后发送的消息首先到达该接收操作也必须等待第一个消息,MPI内容,基本概念点到点通信自定义数据类型集合通信MPI环境管理函数实例,点到点通信详解,MPI通信模式标准模式:Standard同步模式:Buffer缓冲模式:Synchronous预备模式:Ready实现方式阻塞通信(blocking)非阻塞通信(nonblocking),非阻塞,函数的调用总是立即返回,而实际的操作则由MPI系统在后台进行;用户必须随后调用其他函数来等待或查询完成情况;在操作完成之前对相关数据区的操作是不安全的;函数调用是局部的,阻塞与非阻塞的差别

6、,用户发送缓冲区的重用:阻塞的发送:仅当调用了有关结束该发送的语句后才能重用发送缓冲区,否则将导致错误;对于接收方,与此相同,仅当确认该接收请求已完成后才能使用。非阻塞操作,要先调用等待MPI_Wait()或测试MPI_Test()函数来结束或判断该请求,然后再向缓冲区中写入新内容或读取新内容。阻塞发送将发生阻塞,直到通讯完成.非阻塞可将通讯交由后台处理,通信与计算可重叠.,非阻塞发送,一个非阻塞send start调用发起一个发送,但并不完成,而且send start调用会在消息拷贝出发送缓冲区以前返回;另一个send complete调用来完成发送操作,即证实数据已被拷贝出发送缓冲区,缓冲

7、区可重用。通过合适的硬件,在send start完成之后,send complete完成之前,数据向外传送的过程可以和计算同时进行。,非阻塞接收,一个非阻塞的receive start调用发起一个接收操作,这个调用会在消息存入接收缓冲区之前返回,但其返回并不表示接收已完成;另一个receive complete调用来完成接收操作,并证实数据已写入接收缓冲区。通过合适的硬件,在receive start 完成后,receive complete完成之前,数据的写入过程可以和计算同时进行。非阻塞通信可以避免系统缓冲以及内存到内存的复制,计算和通信可以重叠,从而使性能得到改善。,非阻塞发送 MPI_

8、Isend(),int MPI_Isend(void*message/*in*/,intcount/*in*/,MPI_Datatypedatatype/*in*/,intdest/*in*/,inttag/*in*/,MPI_Commcomm/*in*/,MPI_Request*request/*out*/)The“I”stands for“Immediate”,非阻塞发送 MPI_Isend(),提交一个消息发送请求,要求MPI系统在后台完成。MPI_Isend为该发送创建一个请求,并将请求的句柄通过request变量返回给MPI进程。随后MPI_Test/MPI_Wait(查询/等待)等

9、函数可以使用request来判断发送是否完成。,非阻塞发送的四种模式,标准-MPI_Isend()缓冲-MPI_Ibsend()同步-MPI_Issend()就绪-MPI_Irsend(),非阻塞接收 MPI_Irecv(),int MPI_Irecv(void*message/*out*/,intcount/*in*/,MPI_Datatypedatatype/*in*/,intsource/*in*/,inttag/*in*/,MPI_Commcomm/*in*/,MPI_Request*request/*out*/),非阻塞通信的完成,发送的完成:代表发送缓冲区中的数据已送出,发送缓冲区

10、可以重用。它并不代表数据已被接收方接收。数据有可能被缓冲;同步模式:发送完成=接收方已初始化接收,数据将被接收方接收;接收的完成:代表数据已经写入接收缓冲区。接收者可访问接收缓冲区,status对象已被释放。它并不代表相应的发送操作已结束。通过MPI_Wait和MPI_Test来判断通信是否已经完成;,MPI_Wait()函数,int MPI_Wait(MPI_Request*request/*in/out*/,MPI_Status*status/*out*/)当request标识的通信结束后,MPI_Wait才返回。如果通信是非阻塞的,返回时request=MPI_REQUEST_NULL,

11、函数调用是非本地的.MPI_Wait一直等到非阻塞操作真正完成之后才返回,可以认为阻塞通信等于非阻塞通信加上MPI_Wait.,MPI_Wait()应用示例1,MPI_Request request;MPI_Status status;int x,y;if(rank=0)MPI_Isend(,MPI_Wait()应用示例2,intx;MPI_Comm_rank(MPI_COMM_WORLD,.,MPI_Test()函数,int MPI_Test(MPI_Request*request/*in/out*/,int*flag/*out*/,MPI_Status*status/*out*/)MPI_

12、Test用来检测非阻塞操作是否真正结束MPI_Test不论通信是否完成,立即返回。如果通信已经完成,flag=true;否则flag=false,MPI_Test()应用示例,MPI_Requestrequest;MPI_Statusstatus;intx,y,flag;if(rank=0)MPI_Isend(,Request对象的释放,Request参数用来描述非阻塞通信状况的对象,通过对其查询,可以知道与之相应的非阻塞发送和接收是否完成。Request对象只有在通信完成后才会被释放。MPI中提供了函数MPI_Request_free,可不必等待通信完成便可释放request对象。int M

13、PI_Request_free(MPI_Request*request/*in/out*/),消息探测probe,MPI_Probe()和MPI_Iprobe()函数探测接收消息的内容,但并不实际接收消息。用户根据探测到的消息内容决定如何接收这些消息,如根据消息大小分配缓冲区等。在接收未知长度的消息时,可先用MPI_Probe 和MPI_Get_count 得到消息的长度.前者为阻塞方式,即只有探测到匹配的消息才返回;后者为非阻塞,即无论探测到与否均立即返回.,MPI_Probe()函数,int MPI_Probe(int source/*in*/,inttag/*in*/,MPI_Commc

14、omm/*in*/,MPI_Status*status/*out*/)阻塞型探测,直到有一个符合条件的消息到达,返回MPI_ANY_SOURCEMPI_ANY_TAG,MPI_Iprobe()函数,int MPI_Iprobe(int source/*in*/,inttag/*in*/,MPI_Commcomm/*in*/,int*flag/*out*/,MPI_Status*status/*out*/)非阻塞型探测,无论是否有一个符合条件的消息到达,返回。有flag=true;否则flag=false,MPI_Probe()应用示例1,int x;float y;MPI_Comm_rank(

15、comm,MPI_Probe()应用示例2,int x;float y;MPI_Comm_rank(comm,MPI_Cancel()函数,MPI_Cancel用于取消一个尚未完成的通信请求,它在MPI系统中设置一个通信请求取消的标志后立即返回,具体的取消工作由MPI在后台完成。调用MPI_Cancel后,仍然需要调用MPI_Wait/MPI_Test/MPI_Request_free等函数来释放该通信请求Cancel函数用于取消一个被挂起的通信函数,并释放这些资源。一般,其代价是昂贵的,对性能影响较大,尽量少用。MPI_Test_cancelled用来测试一个通信请求是否已经取消,flag=

16、true表明已经取消。,MPI_Cancel()函数,int MPI_Cancel(MPI_Request*request/*in*/)int MPI_Test_cancelled(MPI_Status*status/*in*/,int*flag/*out*/),发送与接收组合,MPI_Sendrecv()函数将一次发送调用和一次接收调用合并进行.它使得MPI 程序更为简洁.更重要的是,MPI 的实现通常能够保证使用MPI_SENDRECV 函数的程序不会出现由于消息收发配对不好而引起的程序死锁.,MPI_Sendrecv(),int MPI_Sendrecv(void*send_buf/*i

17、n*/,intsend_count/*in*/,MPI_Datatypesend_type/*in*/,int dest/*in*/,intsend_tag/*in*/,void*recv_buf/*out*/,intrecv_count/*in*/,MPI_Datatype recv_type/*in*/,intsource/*in*/,intrecv_tag/*in*/,MPI_Commcomm/*in*/,MPI_Status*status/*out*/),send,recv,MPI_Sendrecv(),send-recv操作把发送一个消息到一个目的地和从另一个进程接收一个消息合并到一

18、个调用中。源和目的可以是同一个地方。一个由send-receive发出的消息可以被一个普通接收操作接收,或被一个检查操作检查;一个send-receive操作可以接收一个普通发送操作发送的消息。,MPI_Sendrecv(),一个send-receive操作对穿过一个进程链的切换操作非常有用。如果阻塞的发送和接收被用于这种切换,则需要正确排列发送和接收的顺序(例如偶数进程发送,然后接收,奇数进程先接收,然后发送)以避免循环以赖导致死锁。,MPI_Sendrecv 例 1,MPI_Comm_dup(MPI_COMM_WORLD,MPI_Sendrecv 例2,MPI_Comm_dup(MPI_C

19、OMM_WORLD,MPI_Sendrecv 例3,MPI_Comm_dup(MPI_COMM_WORLD,MPI_Sendrecv_replace(),int MPI_Sendrecv(void*buffer/*in/out*/,intcount/*in*/,MPI_Datatypedatatype/*in*/,int dest/*in*/,intsend_tag/*in*/,intrecv_tag/*in*/,MPI_Commcomm/*in*/,MPI_Status*status/*out*/),空进程,rank=MPI_PROC_NULL的进程称为空进程使用空进程的通信不做任何操作.在

20、很多情况下为通信指定一个“假”的源或目标是非常方便的。这可以简化处理边界的代码,例如,用调用MPI_Sendrecv实现非循环切换的时候。MPI_PROC_NULL这个特殊的值可以用来替换一个调用所要求的源或目标。一个使用MPI_PROC_NULL进程的通信没有动作。一个给MPI_PRC_NULL的发送会立即成功返回。一个从MPI_PROC_NULL的接收会立即成功返回,对接收缓冲区没有任何改变.,空进程,MPI_Get_count(&status,datatype,&count)=count=0status.MPI_SOURCE=MPI_PROC_NULLstatus.MPI_TAG=MPI

21、_ANY_TAG,MPI内容,基本概念点到点通信自定义数据类型集合通信MPI环境管理函数实例,MPI数据类型分类,预定义数据类型自定义数据类型,MPI预定义数据类型,为什么自定义数据类型,MPI 的消息收发函数只能处理连续存储的同一类型的数据.不同系统有不同的数据表示格式。MPI预先定义一些基本数据类型,在实现过程中在这些基本数据类型为桥梁进行转换。派生数据类型:允许消息来自不连续或类型不一致的存储区域,如数组散元与结构类型等的传送.它的使用可有效地减少消息传递的次数,增大通信粒度,并且在收/发消息时避免或减少数据在内存中的拷贝、复制.,数据类型的定义,MPI 数据类型由两个n 元序列构成,n

22、 为正整数.第一个序列包含一组数据类型,称为类型序列(type signature):Typesig=type0,type1,.,typen1.第二个序列包含一组整数位移,称为位移序列(type displacements):Typedisp=disp0,disp1,.,dispn1.位移序列中位移总是以字节为单位计算的.,数据类型的定义(续),构成类型序列的数据类型称为基本数据类型,它们可以是原始数据类型,也可以是任何已定义的数据类型.因此MPI 的数据类型是嵌套定义的.为了以后叙述方便,我们称非原始数据类型为复合数据类型.,类型图(type map),类型序列刻划了数据的类型特征,位移序列

23、则刻划了数据的位置特征。类型序列和位移序列元素的一一配对构成序列的类型图。Typemap=(type0,disp0),(type1,disp1),.,(typen1,dispn1).假设数据缓冲区的起始地址为buff0,则由上述类型图所定义的数据类型包含n 块数据,第i 块数据的地址为buff0+dispi,类型为typei,i=0,1,.,n-1.,类型图(type map)(续),MPI 的原始数据类型的类型图可以写成(类型,0).如MPI_INTEGER 的类型图为(INTEGER,0).位移序列中的位移不必是单调上升的,表明数据类型中的数据块不要求按顺序排放.位移也可以是负的,即数据类

24、型中的数据可以位于缓冲区起始地址之前.,类型图的表示,类型图,类型图的图示,例1,假设数据类型TYPE 类型图为:(integer,4),(integer,12),(integer,0)则语句:int A(100).MPI_Send(A,1,TYPE,.)将发送?,A(1),A(3),A(0),数据类型的大小,指该数据类型中包含的数据长度(字节数),它等于类型序列中所有基本数据类型的大小之和。数据类型的大小就是消息传递时需要发送或接收的数据长度。假设数据类型type的类型图为:(type0,disp0),(type1,disp1),.,(typen1,dispn1)则该数据类型的大小为:,下界

25、、上界与域,下界(lower bound):数据的最小位移上界(upper bound):数据的最大位移加1,再加上一个使得数据类型满足操作系统地址对界要求(alignment)的修正量.域(extent):上界与下界之差,数据类型的对界量,原始数据类型的对界量由编译系统决定复合数据类型的对界量则定义为它的所有基本数据类型对界量的最大值地址对界要求一个数据类型在内存中的(字节)地址必须是它的对界量的整数倍.,C语言中的对界(例2),typedef struct char a;double b;int c;T;,main()T m;printf(sizeof(T)=%d,sizeof(m)=%d

26、n,sizeof(T),sizeof(m);printf(“m.a=%d,m.b=%d,m.c=%dn,(char*),C语言中的对界,struct(char,double,int),char,double,int,MPI_LB 和MPI_UB,MPI提供了两个特殊数据类型MPI_LB 和MPI_UB,称为伪数据类型(pseudo datatype).它们的大小是0,作用是让用户人工指定一个数据类型的上下界.MPI 规定:如果一个数据类型的基本类型中含有MPI_LB,则它的下界定义为:如果一个数据类型的基本类型中含有MPI_UB,则它的上界定义为:,例3,类型图(MPI_LB,-4),(MPI

27、_UB,20),(MPI_DOUBLE,0),(MPI_INTEGER,8),(MPI_BYTE,12)问题:下界为,上界为,域为.,-4,20,24,数据类型查询函数,查询指定数据类型的大小:int MPI_Type_size(MPI_DatatypeDatatype/*in*/,int*size/*out*/)查询指定数据类型的域:int MPI_Type_extent(MPI_DatatypeDatatype/*in*/,MPI_Aint*extent/*out*/),数据类型查询函数,查询指定数据类型的上界:int MPI_Type_ub(MPI_DatatypeDatatype/*i

28、n*/,MPI_Aint*displacement/*out*/)查询指定数据类型的下界:int MPI_Type_lb(MPI_DatatypeDatatype/*in*/,MPI_Aint*displacement/*out*/),MPI自定义数据类型,连续数据类型向量数据类型索引数据类型结构数据类型,连续数据类型的创建,int MPI_Type_contiguous(intcount/*in*/,MPI_Datatypeoldtype/*in*/,MPI_Datatype*newtype/*out*/),同一类型的多次重复,作用:将连续的基类型重复作为一个整体看待,新类型的递交和释放,提

29、交:int MPI_Type_commit(MPI Datatype*datatype)将数据类型映射进行转换或“编译”一种数据类型变量可反复定义,连续提交释放:int MPI_Type_free(MPI_Datatype*datatype)将数据类型设为MPI_DATATYPE_NULL,定义矩阵的一行(例4),在C中定义矩阵的一行float a44;MPI_Datatype C_R;MPI_Comm_dup(MPI_COMM_WORLD,MPI_Recv(&bij,4,MPI_FLOAT,),定义矩阵的一行图示,?如何发送一列?,MPI自定义数据类型,连续数据类型向量数据类型索引数据类型结

30、构数据类型,向量数据类型的生成,int MPI_Type_vector(intcount/*in*/,intblocklen/*in*/,intstride/*in*/,MPI_Datatypeoldtype/*in*/,MPI_Datatype*newtype/*out*/)count 块数(非负整数)blocklength 每块中的元素个数(非负整数)stride每块开始间隔的元素个数(integer),向量数据类型的生成,MPI_Type_vector(count,blocklength,stride,oldtype,newtype)类型重复形成块,多个块按一定的间隔排列间隔可以是以本类

31、型为单位,也可以是以字节为单位,向量数据类型的生成,int MPI_Type_hvector(intcount/*in*/,intblocklen/*in*/,MPI_Aintstride/*in*/,MPI_Datatypeoldtype/*in*/,MPI_Datatype*newtype/*out*/)MPI_Type_vector 中 stride以oldtype 的域为单位MPI_Type_hvector 中stride以字节为单位,定义矩阵的一列(例5),在C中定义矩阵的一列float a44;MPI_Datatype C_C;MPI_Type_vector(4,1,4,MPI_F

32、LOAT,MPI_SEND(&(a01),1,C_C,right,tag,comm),定义矩阵的一列图示,思考,答案,int an+1m+1;MPI_Datatype N_T;MPI_Type_vector(n-1,m-1,m+1,MPI_INT,MPI自定义数据类型,连续数据类型向量数据类型索引数据类型结构数据类型,索引数据类型,int MPI_Type_indexed(intcount/*in*/,intblocklens/*in*/,intindices/*in*/,MPI_Datatypeoldtype/*in*/,MPI_Datatype*newtype/*out*/)count n

33、umber of blocks-also number of entries in indices and blocklens blocklens number of elements in each blockindices displacement of each block in multiples of old_type,索引数据类型,MPI_TYPE_INDEXED(count,array_of_blocklengths,array_of_displacemets,oldtype,newtype)重复形成块,不同的块放到不同的位置,位置的指定可以是以旧数据类型为单位,索引数据类型,i

34、nt MPI_Type_hindexed(intcount/*in*/,intblocklens/*in*/,intindices/*in*/,MPI_Datatypeoldtype/*in*/,MPI_Datatype*newtype/*out*/)count number of blocks-also number of entries in indices and blocklens blocklens number of elements in each blockindices displacement of each block in bytes,例6,问题,MPI_type_ve

35、ctor()与MPI_type_indexed()的区别?MPI_Type_indexed 与MPI_Type_vector 的区别在于每个数据块的长度可以不同,数据块间也可以不等距.,MPI自定义数据类型,连续数据类型向量数据类型索引数据类型结构数据类型,结构数据类型,int MPI_Type_struct(intcount/*in*/,intblocklens/*in*/,MPI_Aintindices/*in*/,MPI_Datatypetypes/*in*/,MPI_Datatype*newtype/*out*/)count number of blocks(integer)block

36、lens number of elements in each blockindices byte displacement of each block(array)types of elements in each block,结构数据类型,MPI_Type_struct(count,array_of_blocklens,array_of_displacemets,array_of_types,newtype)将多个不同的旧数据类型进行组合,而前面的数据类型生成方法都是对一个旧数据类型进行重复。,例7,数据的打包与拆包,在MPI 中,通过使用特殊数据类型MPI_PACKED,用户可以将不同的

37、数据进行打包后再一次发送出去,接收方在收到消息后再进行拆包.为了与早期其它并行库兼容MPI不建议用户进行显式的数据打包,数据的打包,int MPI_Pack(void*inbuf/*in*/,intincount/*in*/,MPI_Datatype datatype/*in*/,void*outbuf/*in*/,intoutsize/*in*/,int*position/*in/out*/,MPI_Commcomm/*in*/)该函数将缓冲区inbuf 中的incount 个类型为datatype 的数据进行打包.打包后的数据放在缓冲区outbuf 中.outsize 给出的是outbuf

38、 的总长度(字节数,供函数检查打包缓冲区是否越界用).,数据的打包,position 是打包缓冲区中的位移,第一次调用MPI_Pack 前用户程序将position 设为0随后MPI_Pack 将自动修改它,使得它总是指向打包缓冲区中尚未使用部分的起始位置每次调用MPI_Pack 后的position 实际上就是已打包的数据的总长度,例8,MPI_Comm_dup(MPI_COMM_WORLD,数据的拆包,int MPI_Unpack(void*packbuf/*in*/,intinsize/*in*/,int*position/*in/out*/,void*outbuf/*out*/,int

39、outcount/*in*/,MPI_Datatype datatype/*in*/,MPI_Commcomm/*in*/)从packbuf 中拆包outcount 个类型为datatype 的数据到outbuf 中.函数中各参数的含义与MPI_Pack 类似,只不过这里的packbuf和insize 对应于MPI_Pack中的outbuf 和outsize,而outbuf 和outcount 则对应于MPI_Pack 中的inbuf 和incount.,例9,MPI_Comm_dup(MPI_COMM_WORLD,数据类型函数汇总,上机试验1,实现点到点通信,并计算通信带宽实现结点间的循环消

40、息传递,并计算通信带宽012345-n-10,尝试非阻塞通信方式,上机实验2,将矩阵A 的转置拷贝到矩阵B 中a(0,0)a(0,1)a(0,n)a(1,0)a(1,1)a(1,n)a(m,0)a(m,1)a(m,n),Type1,矩阵转置,多种实现方法,矩阵转置,#include#include“mpi.h”#define N 10int main(int argc,char*argv)intmy_rank,tag=0,aNN,bNN,i,j;MPI_Status status;MPI_Commcomm;MPI_Datatypecolumn_type;MPI_Datatype raw_typ

41、e;MPI_Init(,矩阵转置,MPI_Type_vector(N,1,N,MPI_INT,矩阵转置,MPI_Type_vector(N,1,N,MPI_INT,MPI内容,基本概念点到点通信自定义数据类型集合通信MPI环境管理函数实例,组通信概述,通信域限定哪些进程参加以及组通信的上下文组通信调用可以和点对点通信共用一个通信域MPI保证由组通信调用产生的消息不会和点对点调用产生的消息相混淆在组通信中不需要通信消息标志参数组通信一般实现三个功能通信、同步和计算通信功能主要完成组内数据的传输同步功能实现组内所有进程在特定地点在执行进度上取得一致计算功能要对给定的数据完成一定的操作,三种通信方式

42、,一对多、多对一、多对多(按通信方向),组通信中的同步,点到点通信的完成,重新使用缓冲区一个进程组通信的完成,并不表示其他所有进程的组通信都已经完成。同步操作,完成各个进程之间的同步,协调各个进程的进度和步伐。,同步函数 MPI_Barrier,int MPI_Barrier(MPI_Commcomm/*in*/)MPI 唯一的一个同步函数,当comm中的所有进程都执行这个函数后才返回。如果有一个进程没有执行此函数,其余进程将处于等待状态。在执行完这个函数之后,所有进程将同时执行其后的任务。,组通信中的同步,MPI_Barrier(comm),实例:MPI_Barrier,MPI_Init(,

43、组通信中的计算,组通信除了通信和同步之外,还可进行计算。MPI组通信的计算功能是分三步实现的首先是通信的功能,即消息根据要求发送到目的进程,目的进程也已经接收到了各自所需要的消息然后是对消息的处理即计算部分。MPI组通信有计算功能的调用都指定了计算操作,用给定的计算操作对接收到的数据进行处理最后一步是将处理结果放入指定的接收缓冲区,组通信中的计算图示,全局数据运算Reduce,MPI_Reduce将组内每个进程输入缓冲区中的数据按给定的操作op进行运算,并将结果返回到根进程的输出缓冲区中。输入缓冲区由参数sendbuf、count和datatype定义。输出缓冲区由参数recvbuf、coun

44、t和datatype定义要求两者的元素数目和类型都必须相同。所有组成员都用同样的count、datatype、op、root和comm来调用此例程,故所有进程都提供长度相同、元素类型相同的输入和输出缓冲区每个进程可能提供一个元素或一系列元素,组合操作依次针对每个元素进行,全局归约MPI_Reduce,int MPI_Reduce(void*openand/*in*/,void*result/*in*/,intcount/*in*/,MPI_Datatypedatatype/*in*/,MPI_Opoperator/*out*/,introot/*in*/,MPI_Commcomm/*in*/)

45、,openand操作数(发送缓冲区)起始地址result接收缓冲区(结果)的地址count发送缓冲区数据个数operator归约操作符,MPI_Reduce图示,归约求和图示,P0,P1,P2,A0+B0+C0,MPI_Reduce,A1+B1+C1,A2+B2+C2,MPI预定义操作,数据广播MPI_Bcast,MPI_Bcast完成从root进程将一条消息广播发送到组内的所有进程,包括它本身在内其执行结果是将根进程通信消息缓冲区中的消息拷贝到其他所有进程中去组内所有进程不管是root进程本身还是其它的进程都使用同一个通信域comm和根标识root 数据类型datatype可以是预定义或派生

46、数据类型其它进程指定的通信元素个数count,、数据类型datatype必须和根进程指定的count和datatype保持一致,MPI_Bcast,int MPI_Bcast(void*buffer/*in/out*/intcount/*in*/MPI_Datatypedatatype/*in*/introot/*in*/MPI_Commcomm/*in*/),buffer通信消息缓冲区的起始地址count将广播出去/或接收的数据个数datatype广播/接收数据的数据类型root广播数据的根进程的标识号comm通信域,MPI_Bcast图示,databuf.MPI_Bcast();.,dat

47、a.MPI_Bcast();.,data.MPI_Bcast();.,Process 0myrank=0,Process 1myrank=1,Process p-1myrank=p-1,A,A,A,A,MPI_Bcast,P0,P1,P2,P3,P0,P1,P2,P3,实例:MPI_Bcast,MPI_Init(,实例:求向量点积,p0,p0,p1,p2,p3,p4,求向量点积计算流程,向量点积代码1,#define N 20000main(int argc,char*argv)int xN,yN,gsize,size,myrank,i;float local_sum=0.0,sum;MPI_

48、Status status;MPI_Comm comm;MPI_Init(,向量点积代码2,if(myrank=0)/*给两个向量x,y 赋值*/for(i=0;iN;i+)xi=i+1;yi=i+1;/*进程0广播向量x和y到各个进程*/MPI_Bcast(x,N,MPI_INT,0,comm);MPI_Bcast(y,N,MPI_INT,0,comm);size=N/gsize;for(i=0;isize;i+)/*各进程并行计算局部向量点积*/local_sum=local_sum+xmyrank*size+i*ymyrank*size+i;MPI_Reduce(,数据收集MPI_Gat

49、her,把所有进程(包括root)的数据聚集到root 进程中,并且按顺序存放在接收缓冲区中.其结果就象一个进程组中的N个进程(包括root)都执行了一个发送调用,同时根进程执行了N次接收调用.,MPI_Gather函数,int MPI_Gather(void*sendbuf/*in*/intsendcount/*in*/MPI_Datatypesendtype/*in*/void*recvbuf/*out*/intrecvcount/*in*/MPI_Datatyperecvtype/*in*/introot/*in*/MPI_Commcomm/*in*/),sendbuf 发送缓冲区起始地

50、址sendcount 发送缓冲区数据个数sendtype 发送缓冲区数据类型,recvbuf 接收缓冲区起始地址recvcount 接收缓冲区数据个数recvtype 接收缓冲区数据类型,Root ONLY,MPI_Gather函数详解,从各个进程收集到的数据一般是互不相同的收集调用每个进程的发送数据个数sendcount和发送数据类型sendtype都是相同的,都和根进程中接收数据个数recvcount和接收数据类型recvtype相同。root和comm在所有进程中都必须是一致的根进程中指定的接收数据个数是指从每一个进程接收到的数据的个数而不是总的接收个数对于所有非根进程接收消息缓冲区被忽

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/施工/环境 > 项目建议


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号