《MPI并行程序设计.ppt》由会员分享,可在线阅读,更多相关《MPI并行程序设计.ppt(80页珍藏版)》请在课桌文档上搜索。
1、消息传递并行程序设计,消息传递并行程序设计:,指用户必须通过显式地发送和接收消息来实现处理机间的数据交换。在这种并行编程中,每个并行进程均有自己独立的地址空间,相互之间访问不能直接进行,必须通过显式的消息传递来实现。这种编程方式是大规模并行处理机(MPP)和机群(Cluster)采用的主要编程方式。,消息传递并行程序设计,并行计算粒度大,特别适合于大规模可扩展并行算法:,由于消息传递程序设计要求用户很好地分解问题,组织不同进程间的数据交换,并行计算粒度大,特别适合于大规模可扩展并行算法。,消息传递是当前并行计算领域的一个非常重要的并行程序设计方式。,什么是MPI?,MPI(Massage Pa
2、ssing Interface):是消息传递函数库的标准规范,由MPI论坛开发,支持Fortran和C。,一种新的库描述,不是一种语言。共有上百个函数调用接口,在Fortran和C语言中可以直接对这些函数进行调用。从语法上,它遵守所有对库函数/过程的调用规则,与一般的函数/过程没有区别。MPI是一种标准或规范的代表,而不是特指某一个对它的具体实现。一个正确的MPI程序,可不加修改在所有的并行机上运行。MPI是一种消息传递编程模型,并成为这种编程模型的代表和事实上的标准。最终目标是服务于进程间通信。,MPI的发展过程,发展的两个阶段:,MPI 1.1:1995 MPICH:是一种最重要的MPI实
3、现,每当MPI推出新的版本,就会有相应的MPICH的实现版本。由美国Argonne国家实验室和密西西比州立大学联合开学,具有更好的可移植性。MPI 1.22.0:动态进程,并行I/O,支持F90和C+。,为什么要用MPI?优点,高可移植性:,MPI已在IBM PC机上、MS Windows上、所有主要的Unix工作站上和所有主流的并行机上得到实现。使用MPI作消息传递的C或Fortran并行程序可不加改变地运行在IBM PC、MS Windows、Unix工作站、以及各种并行机上。消息传递方式是广泛应用于多类并行机的一种模式,特别是分布存储并行机。这种模式在一些重要的计算应用中已取得了实质性进
4、步。,为什么要用MPI?优点,MPI是被正式的详细说明的:它已经成为一个标准。消息传递标准的定义能提供给生产商清晰定义的程序库,以便他们能有效地实现这些库或在某些情况下为库程序提供硬件支持,因此加强了扩展性。MPI有完备的异步通信:使得send,receive能与计算重叠。可以有效的在MPP上或Cluster上用MPI编程。,MPI+C 实现的“Hello World!”,#include#include mpi.h main(int argc,char*argv)MPI_Init(,MPI+C实现的“Hello World!”,mpi.h是MPI标准规定的,每个MPI实现都要包含。它提供用户
5、MPI程序需要的所有必要的原型和外部变量声明。MPI函数返回出错代码或MPI_SUCCESS成功标志。MPI-前缀,且只有MPI以及MPI_标志后的第一个字母大写,其余小写。MPI函数的参数被标志为以下三种类型:IN:参数在例程的调用中不会被修正。OUT:参数在例程的调用中可能会被修正。INOUT:参数在一些例程中为IN,而在另一些例程中为OUT.,MPI初始化-MPI_Init,int MPI_Init(int*argc,char*argv)MPI_INIT(IERROR)MPI_Init是MPI程序的第一个调用,它完成MPI程序的所有初始化工作。所有的MPI程序的第一条可执行语句都是这条语
6、句。启动MPI环境,标志并行代码的开始。并行代码之前,第一个mpi函数(除MPI_Initialize()外)。要求main必须带参数运行,否则出错。,MPI结束-MPI_Finalize,int MPI_Finalize(void)MPI_FINALIZE(IERROR)MPI_Finalize是MPI程序的最后一个调用,它结束MPI程序的运行,它是MPI程序的最后一条可执行语句,否则程序的运行结果是不可预知的。标志并行代码的结束,清理和关闭除主进程外的其它进程。之后串行代码仍可在主进程(rank=0)上运行(如果必须)。,MPI程序的的编译与运行,mpif77 hello.f 或 mpic
7、c hello.c 默认生成a.out的可执行代码。mpif77 o hello hello.f 或 mpicc o hello hello.c生成hello的可执行代码。mpirun np 4 a.out mpirun np 4 hello4 指定np的实参,表示进程数,由用户指定。a.out/hello 要运行的MPI并行程序。,输出文件命名,Hello是如何被执行的?,SPMD:Single Program Multiple Data(SPMD),开始写MPI并行程序,在写MPI程序时,我们常需要知道以下两个问题的答案:由多少个进程来进行并行计算?我是哪一个进程?,两个函数,MPI 提供
8、了下面两个函数来回答上述问题:用MPI_Comm_size 获得进程个数 p int MPI_Comm_size(MPI_Comm comm,int*size);这一调用返回给定的通信域中所包含的进程的个数,不同的进程通过这一调用得知在给定的通信域中一共有多少个进程在并行执行。用MPI_Comm_rank 获得进程的一个叫rank的值,该 rank值为0到p-1间的整数,相当于进程的IDint MPI_Comm_rank(MPI_Comm comm,int*rank);这一调用返回调用进程在给定的通信域中的进程标识号,有了这个标识号,不同的进程就可以将自身和其它的进程区分开,实现进程的并行和协
9、作。,更新的“Hello World!”,#include#include mpi.h int main(int argc,char*argv)int myid,numprocs;MPI_Init(,运行结果,dairnode01$mpicc o hello1 hello1.cdairnode01$mpirun-np 4 hello1Hello,World!I am 0 of 4Hello,World!I am 1 of 4Hello,World!I am 2 of 4Hello,World!I am 3 of 4dairnode01$,计算机打印字符,输入的命令,通信字MPI_COMM_WO
10、RLD,MPI_Comm_size和MPI_Comm_rank两个函数都用到了同一个参数MPI_COMM_WORLD。MPI_COMM_WORLD是一个预定的通信域(communicator),+包括进程组和通信上下文,用于描述进程间的通信关系。+进程组是进程的有限,有序集。+通信上下文如同系统设计的超级标签,用于安全地区别不同的通信,以免互相干扰。每个通信域的上下文都不同,一个上下文中的消息发送不能在另一个上下文中被接收,通信上下文不是显示的MPI对象,它们仅作为通信域实现的一部分出现。+它在执行MPI_Initb函数后自动生成。MPI通信操作函数中必不可少的参数,用于限定参加通信的进程的范
11、围。,函数MPI_Comm_size和MPI_Comm_rank查询MPI_COMM_WORLD以获得应用中MPI进程的总数并为这些MPI进程分别获得一个唯一的编号。获取的值放在变量size和rank。,MPI程序的框架结构,消息发送和接收,MPI_SEND(buf,count,datatype,dest,tag,comm)IN buf 发送缓冲区的起始地址(可选类型)IN count 将发送的数据的个数(非负整数)IN datatype 发送数据的数据类型 IN dest 目的进程标识号rank(整型)IN tag 消息标签,用于识别不同的消息(整型)IN comm 通信域(句柄)int M
12、PI_Send(void*buf,int count,MPI_Datatype datatype,int dest,int tag,MPI_Comm comm)一个消息好似一封信。需要定义消息的内容,还需要定义消息的发送者或接收者,前者(buf,count,datatype)称为消息缓冲,后者(dest,tag,comm)称为消息信封。,说明,MPI_Send将发送缓冲区中的count个datatype数据类型的数据发送到目的进程,目的进程在通信域的标识号是dest,本次发送的消息标志是tag,这一标志的目的是把本次发送的消息和本进程向同一目的进程发送的其他消息区别开来。MPI_Send操作指
13、定的发送缓冲区是由count个类型为datatype的连续数据空间组成,起始地址为buf。注意:不是以字节计数,而是以数据类型为单位指定消息的长度。其中datatype数据类型:MPI的预定义类型或用户自定义。通过使用不同的数据类型调用MPI_Send,可以发送不同类型的数据。,消息发送和接收,MPI_RECV(buf,count,datatype,source,tag,comm,status)OUT buf 接收缓冲区的起始地址(可选类型)IN count 最多可接收的数据的个数(非负整数)IN datatype 接收数据的数据类型 IN source 接收数据的来源 即发送数据的进程的进程
14、标识号(整型)IN tag 消息标志,与相应的发送操作的消息标识rank相匹配(整型)IN comm 本进程和发送进程所在的通信域(句柄)OUT status 返回状态,status对象,包含实际接收到的消息的有关信息int MPI_Recv(void*buf,int count,MPI_Datatype datatype,int source,int tag,MPI_Comm comm,MPI_Status*status),说明,MPI_Recv从指定的进程source接收消息,并且该消息的数据类型和接收进程指定的datatype和tag相一致,接收到的消息所包含的数据元素的个数最多不能超过
15、count。接收缓冲区是由count个类型为datatype的连续元素空间组成,起始地址为buf。接收到消息的长度被确定。如果大小缓冲区的长度会发生溢出;如果一个短于接收缓冲区的消息到达,那么只有相应于这个消息的那些地址被修改。count可以为零,此时消息的数据部分是空的。其中datatype数据类型:MPI的预定义类型或用户自定义。通过指定不同的数据类型调用MPI_Recv,可以发送不同类型的数据。,返回状态status,返回状态变量status用途很广,它是MPI定义的一个数据类型,使用之前需要用户为它分配空间。在C实现中,状态变量是由至少三个域组成的结构类型,这三个域分别是:MPI_SO
16、URCE,MPI_TAG,MPI_ERROR。它还可以包括其他的附加域。通过对status.MPI_SOURCE,status.MPI_TAG和staus.MPI_ERROR的引用就可以得到返回状态中所包含的发送数据进程的标识、发送数据使用的tag标识和本接收操作返回的错误代码。除了以上三个信息之外,对status变量执行MPI_GET_COUNT调用可得到接收到的消息的长度信息。,MPI消息,MPI消息包括信封和数据两个部分,信封指出了发送或接收消息的对象及相关信息,而数据是本消息将要传递的内容。数据:信封:,MPI消息,一个消息好似一封信。需要定义消息的内容,还需要定义消息的发送者或接收者
17、,前者称为消息缓冲,后者称为消息信封。,什么是缓冲区?,应用程序中说明的变量,在消息传递语句中又用作缓冲区的起始位置。也可表示由系统(不同用户)创建和管理的某一存储区域,在消息传递过程中用于暂存放消息.也被称为系统缓冲区。用户可设置一定大小的存储区域,用作中间缓冲区以保留可能出现在其应用程序中的任意消息。,系统缓冲区,用户指定缓冲区,用户缓冲区,一个简单的发送和接收例子,一个进程(进程0)向另一个进程(进程1)发送一条消息,该消息是一个字符串“Hello,process 1”。进程1在接收到该消息后,将这一消息打印到屏幕上。,#include#include main(int agrc,cha
18、r*argv)char message20;int myrank;MPI_Init(,一个简单的发送和接收例子,MPI_Send(message,strlen(message),MPI_CHAR,1,99,MPI_COMM_WORLD);/*先将字符串拷贝到发送缓冲区message中,然后调用MPI_Send语句将它发出,用strlen(message)指定消息的长度,用MPI_CHAR指定消息的数据类型,1指明发往进程1,使用的消息标识是99,MPI_COMM_WORLD是包含是包含本进程0和接收消息的进程1的通信域。发送方和接收方必须在同一个通信域。由通信域来统一协调和控制消息的发送和接收
19、*/else if(myrank=1)/*若是进程1*/,一个简单的发送和接收例子,MPI_Recv(message,20,MPI_CHAR,0,99,MPI_COMM_WROLD,/*进程1直接执行接收消息的操作,这里它使用message作为接收缓冲区。可见,同一个变量在发送进程和接收进程中的作用是不同的。它指定接收消息的最大长度为20,消息的数据类型为MPI_CHAR字符型,接收的消息来自进程0,而接收消息携带的标识必须为99,使用的通信域也是MPI_COMM_WORLD,接收完成后的各种状态信息存放在status中。接收完成后,直接将接收到的字符串打印在屏幕上。*/MPI_Finaliz
20、e()/*MPI程序结束*/,MPI预定义的数据类型,MPI预定义的数据类型,如果宿主语言有附加的数据类型,那么MPI应提供附加的相应数据类型,如下表所示:,现在您已经能够用MPI进行并行编程了!,点对点通信,点对点通信(Point-to-Point Communication)是MPI中比较复杂的一部分,它有两种消息传递机制:阻塞的和非阻塞的。,通信模式,通信模式指的是缓冲管理以及发送方和接收方之间的同步方式。MPI支持4种通信模式。即标准通信模式、缓冲通信模式、同步通信模式和就绪通信模式。,标准通信模式,在标准通信模式中,是否对发送的数据进行缓冲由MPI来决定,而不是由用户程序来控制的。如
21、果MPI决定缓存将要发出的数据,发送操作不管接收是否已经启动都可以执行,否则只有等待接收操作启动后才能正确返回。,缓冲通信模式,在缓冲通信模式中,1)用户直接对通信缓冲区进行申请、使用和释放。2)不管接收是否已经启动,发送操作都可以执行,但是在发送消息之前必须有缓冲区,这由用户保证。3)消息发送能否进行及能否正确返回,不依赖于接收进程,完全依赖于是否有足够的通信缓冲区可用。由MPI_Buffer_attach来申请和MPI_Buffer_detach和收回申请的缓冲区。,同步通信模式,在同步通信模式中,发送不依赖于接收进程相应的接收操作是否已经启动,但是同步发送必须等到相应的接收进程开始后才可
22、以正确返回。同步发送返回后,发送缓冲区中的数据已经全部被系统缓冲区缓存并且已经开始发送。,就绪通信模式,在就绪通信模式中,1)只有当接收进程的接收操作已经启动时,才可以在发送进程启动发送操作;2)对于非阻塞发送操作的正确返回,并不意味着发送已完成,但对于阻塞发送的正确返回,则发送缓冲区可重复使用;3)就绪通信模式的特殊之处就在于它要求接收操作先于发送操作而被启动。,MPI的几个函数,MPI_Init(int*argc,char*argv)/初始化MPI系统,其参数由main()提供MPI_Initialized(int*flag)/检测MPI系统是否已初始化,唯一可在MPI_Init()前使用
23、的函数。如已调用MPI_Init(),返回flag=true,否则flag=false。MPI_Comm_size()/得到通信域的进程数MPI_Comm_rank()/得到通信域内进程的标号MPI_Finalize()/退出MPI系统,MPI的几个函数,MPI_Abort(MPI_Comm comm,int errorcode)/异常终止MPI程序。-在出现致命错误而希望异常终止MPI程序时执行-MPI系统会设法终止comm通信域中所有进程-输出整型参数errorcode,将被作为进程的退出码返回给系统。MPI_Get_processor_name(char*name,int*resultl
24、en)/获取处理器名称-在返回的name中存储进程所在处理器的名称-resultlen存放返回名字所占字节,应提供参数name不小于MPI_MAX_PRCESSOR_NAME个字节的存储空间。,MPI的几个函数,MPI_Get_version(int*version,int*subversion)/获取MPI版本号。-若MPI的版本号为2.0,则返回的version=2,subversion=0MPI_Wtime(void)/返回时间-返回调用时刻的时间,用浮点数表示称数-经常用来计算程序运行时间。rank=MPI_PROC_NULL/空进程-使用空进程的通信不做任何操作-向MPI_PROC_
25、NULL发送的操作总是成功并立即返回-从MPI_PROC_NULL接收的操作总是成功并立即返回,且接收缓冲区内容为随机数。,任意源和任意标识,一个接收操作对消息的选择是由消息的信封管理的。如果消息的信封与接收操作所指定的值source,tag和comm相匹配,那么这个接收操作能接收这个消息。此外,接收者可以给source指定一个任意值MPI_ANY_SOURCE,标识任何进程发送的消息都可接收,即本接收操作可以匹配任何进程发送的消息,但其它的要求还必须满足,如tag的匹配;如果给tag一个任意值MPI_ANY_TAG,则任何tag都是可以接收的。这类似于统配符的概念。上述两个任意值可以同时使用
26、或分别单独使用。但是不能给comm指定任意值。,点对点通信定义,两个进程之间的通信源进程发送消息到目标进程目标进程接受消息通信发生在同一个通信域内进程通过其在通信域内的标号表示,MPI系统的通信方式都建立在点对点通信之上。,四种通信模式,标准通信模式、缓冲通信模式、同步通信模式和就绪通信模式。这四种通信模式是根据以下不同的情况来区分的:1)是否需要对发送的数据进行缓存?2)是否只有当接收调用执行后才可以执行发送操作?3)什么时候发送调用可以正确返回?4)发送调用正确返回是否,意味着发送已完成?即发送缓冲区可否被覆盖?即发送数据是否已到达接收缓冲区?针对这些情况,MPI给出了不同的通信模式。,阻
27、塞式和非阻塞式点对点通信两种消息传递机制,对于阻塞的方式,它必须等到消息从本地送出之后,才可以执行后续的语句,保证了消息缓冲区等资源的可再用性;而非阻塞的方式不须等到消息从本地送出,就可以执行后续的语句,从而允许通信和计算的重叠,利用合适的硬件可使得计算和数据通信同时执行,但是非阻塞调用的返回并不保证资源的可再用性。,阻塞和非阻塞点对点通信,阻塞式点对点通信,消息传递成功-发送进程需指定一个有效的目标接收进程-接收进程需指定一个有效的源发送进程-接收和发送消息的进程要在同一个通信域内-接收和发送消息的tag要相同-接收缓冲区要足够大,编写安全的MPI程序,发送和接收是成对出现的,如果通信调用的
28、顺序使用不当,很容易造成死锁。如下程序总会死锁。,ACBD,编写安全的MPI程序,进程0的第一条接收语句A能否完成取决于进程1的第二条发送语句,即A依赖于D。从执行次序上可以明显地看出,进程0和进程1发送消息的语句C的执行又依赖于它前面的接收语句A的完成,即C依赖于A。同时,进程1的第一条接收语句B能否完成取决于进程0的第二条发送语句C的执行,即B依赖于C,从执行次序上可以明显地看出,向进程0发送消息的语句D的执行又依赖于B的完成,故有A依赖于D,D又依赖于B,B依赖于A,形成了一个环,进程0和进程1相互等待,彼此都无法执行下去,必导致死锁。,编写安全的MPI程序,若两个进程需要相互交换数据,
29、在两个进程中首先都进行接收调用显然是不合适的,那么,同时先进行发送调用的结果又是如何的呢?,ACB D,编写安全的MPI程序,由于进程0或进程1的发送需要系统提供缓冲区,如果缓冲区不足,则进程0或进程1的发送将无法完成,相应的,进程1和进程0的接收也无法正确完成。显然对于需要相互交换数据的进程,直接将两个发送语句写在前面也是不安全的。,编写安全的MPI程序,一个安全的通信调用次序,要求两个进程相互交换数据时,一定要将它们的发送和接收操作按照次序进行匹配,即一个进程的发送操作在前,接收操作在后;而另一个进程的接收操作在前,发送操作在后,前后两个发送和接收操作相互匹配。,ACDB,编写安全的MPI
30、程序,C的完成只需要A完成,而A的完成只要有对应的D存在,则不需要系统提供缓冲区也可以进行,因此,A总能够完成,那么D也一定能完成。当A和D完成后,B的完成只需要相应的C,不需要缓冲区也能完成,因此B和C也一定能完成,所以这样的通信形式是安全的。,阻塞式点对点通信,标准阻塞通信,-是否对发送数据进行缓存,由MPI系统决定,而非程序员。-阻塞:发送成功,意味:1)消息被接收完毕;2)或者消息被缓存接收成功,消息已被成功接收。,阻塞式点对点通信,-MPI_Send-MPI_Recv-MPI_Get_count-MPI_Sendrecv-MPI_Sendrecv_replace,阻塞式点对点通信,查
31、询接收到的消息长度int MPI_Get_count(MPI_Status status,MPI_Datatype datatype,int*count)IN status 接收消息时返回的状态IN datatype 接收消息时返回的类型OUT Count 接收消息时数组元素的个数,-该函数在count中返回数据类型的个数,即消息长度。-count属于MPI_Status结构的一个域,但不能被用户直接访问。,阻塞式点对点通信,发送和接收的捆绑MPI_Sendrecv()。即把发送一个消息到一个目的地和从另一个进行接收一个消息合并到一个调用中,源和目的可以是相同的,它可以有效地避免单独书写发送或
32、接收操作时,由于次序的错误而造成的死锁。这是因为该操作是由通信系统来实现,系统会优化通信次序,从而有效地避免不合理的通信次序,最大限度地避免死锁的产生。函数原型为:int MPI_Sendrecv(void*sendbuf,int sendcount,MPI_Datatype sendtype,int dest,int sendtag,void*recvbuf,int recvcount,MPI_Datatype recvtype,int source,int recvtag,MPI_Comm comm,MPI_Status*status)IN sendbuf 所要发送消息数据的首地址IN s
33、endcount 发送消息数组元素的个数IN sendtype 发送消息的数据类型IN dest 接收消息的进程编号IN sendtag 发送消息标签,阻塞式点对点通信,OUT recvbuf 接收消息数据的首地址IN recvcount 接收消息数组元素的最大个数IN recvtype 接收消息的数据类型IN Source 发送消息的进程编号IN recvtag 接收消息标签IN comm 通信子OUT status 接收消息时返回的状态,阻塞式点对点通信,捆绑发送和接收,收发使用同一缓存区int MPI_Sendrecv_replace(void*sendbuf,int count,MPI
34、_Datatype datatype,int dest,int sendtag,int source,int recving,MPI_Comm comm,MPI_Status*status)OUT buf 发送和接收消息数据的首地址IN count 发送和接收消息数组元素的个数IN dest 接收消息的进程编号IN sendtag 发送消息标签IN source 发送消息的进程编号IN recvtag 接收消息标签IN comm 通信子OUT status 接收消息时返回的状态,-该操作等价于当前进程先执行一个发送函数再执行一个接收函数;MPI系统保证其消息发出后再接收消息。-MPI_Send
35、recv发收使用不同的缓冲区;该函数使用同一缓存区。,阻塞式消息发送模式,按着发送方式和接收方状态要求的不同分类,-四个函数拥有完全一样的入口参数-共用一个标准的消息接受函数-发送返回后,发送缓存区可以被释放或者重新使用。,标准消息发送函数MPI_Send,-发送操作不管接收操作是否启动,都可以开始。-发送返回的条件:1)当消息小于MPI系统为每个进程设置的最大消息缓存区MPI_BUFFER_SIZE,发送数据被MPI系统缓存,此时不要求接收操作收到发送数据;2)不缓存,则数据被接收到接收缓存区。,缓存消息发送函数MPI_Bsend,-发送操作不管接收操作是否启动,都可以开始。-进程直接对缓存
36、区进行控制,用户直接对通信缓存区进行申请、使用、翻译。要求:1)发送消息前必须有足够的缓存可用,否则发送失败;2)缓存发送返回后,不意味申请的缓存区可自由使用,须等待消息发送出去方可。-优势:发送操作在缓存了发送数据后,可立刻返回。,缓存消息发送函数MPI_Bsend,缓存区申请:int MPI_Buffer_attach(void*buffer,int size)-OUT buffer 缓冲区初始地址;OUT size 以字节为单位的缓冲区大小-可调用MPI_Type_size函数来确定数据类型所占字节数。缓存区大小=数据长度+常数,常数用于MPI系统管理提交的缓存区,是必须的。-同一时刻,
37、一个进程只能定义一个缓存区,即进程再定义另一个,需要释放已经定义的。,缓存区释放:int MPI_Buffer_detach(void*buffer,int size)-此函数为阻塞式调用,等到该缓存消息发送后才释放返回。,同步消息发送函数MPI_Ssend,-发送操作不管接收操作是否启动,都可以开始。-发送返回条件,需在标准模式上确认接收方已经开始接收数据。1)发送数据被存放系统缓存区,需接收方开始接收,发送才能返回;2)发送数据没有被系统缓存,则需要消息发送完毕后,发送才能返回。-优势:这种模式发送和接收最为安全。,就绪消息发送函数MPI_Rsend,-发送操作必须要求接收操作启动,才可开
38、始。1)启动接受操作,意味着接收进程正等待接收发送的消息;2)若发送操作启动而相应接收操作没有启动,发送操作将出错。-优势:减少消息发送接收时间开销,可能获得好的计算性能。,阻塞式消息发送模式,阻塞和非阻塞点对点通信两种消息传递机制,非阻塞式点对点通信,非阻塞式点对点通信,-MPI_Isend-MPI_Irecv-MPI_Wait-MPI_Probe/MPI_Iprobe-MPI_Request_free-MPI_Cancel-MPI_Test_cancelled,非阻塞式点对点通信,Int MPI_Isend(void*buf,int count,MPI_Datatype datatype,
39、int dest,int tag,MPI_Comm comm,MPI_Request*request)-该函数启动接收,并立即返回,并不意味着发送成功。-MPI系统会在后台完成消息发送-函数为该发送操作创建了一个请求,描述非阻塞通信状况,通过request变量返回。-request可供之后查询和等待函数使用,非阻塞式发送,非阻塞式点对点通信,Int MPI_Irecv(void*buf,int count,MPI_Datatype datatype,int source,int tag,MPI_Comm comm,MPI_Request*request)-该函数仅提交了一个消息发送请求,并立即
40、返回,并不意味着接收成功。-MPI系统会在后台完成消息接收-函数为该接收创建了一个请求,通过request变量返回。-request可供之后查询和等待函数使用,非阻塞式接收,非阻塞式点对点通信,Int MPI_Wait(MPI_Request*request,MPI_Status*status)Int MPI_Test(MPI_Request*request,int*flag,MPI_Status*status)-MPI_Wait阻塞等待通信函数完成后返回;MPI_Test检测某通信,不论其是否完成,都立即返回,如果通信完成,则flag=true-当等待或检测的通信完成时,通信请求reques
41、t被设置成MPI_REQUEST_NULL-考察接收请求,status返回与MPI_Recv一样;发送请求,则不确定-MPI_Test返回时,当flag=false,status不被赋值,等待、检测一个通信请求的完成,非阻塞式点对点通信,MPI_Request request;MPI_Status status;int x,y;if(rank=0)MPI_Isend(当request标识的通信结束后,MPI_Wait()才返回,MPI_Wait()应用示例,非阻塞式点对点通信,MPI_Request request;MPI_Status status;int x,y,flag;if(rank=
42、0)MPI_Isend(,MPI_Test()应用示例,非阻塞式点对点通信,Int MPI_Waitall(int count,MPI_Request*array_of_requests,MPI_Status*array_of_statuses)Int MPI_Testall(int count,MPI_Request*array_of_requests,int*flag,MPI_Status*array_of_statuses)-count表示通信请求的个数-array_of_requests是一组非阻塞通信的请求-array_of_status返回该组通信完成的状态-flag表示全部通信是
43、否完成,若完成flag=true-MPI_Testall返回时,当flag=false,array_of_statuses不被赋值,等待、检测一组通信请求的全部完成,非阻塞式点对点通信,Int MPI_Waitsome(int incount,MPI_Request*array_of_requests,int outcount,int*array_of_indices,MPI_Status*array_of_statuses)Int MPI_Testsome(int incount,MPI_Request*array_of_requests,int outcount,int*array_of_
44、indices,MPI_Status*array_of_statuses)-MPI_Waitsome等待至少一个通信完成才返回-outcount表示通信成功完成的个数-array_of_indeices存储完成的通信在array_of_requests中的位置-array_of_statuses返回完成通信的状态,其他不被赋值-MPI_Testsome返回时若没有一个通信完成,则outcount=0-MPI_Testsome返回时,当flag=false,array_of_statuses不被赋值,等待、检测一组通信请求的部分完成,非阻塞式点对点通信,Int MPI_Probe(int sou
45、rse,int tag,MPI_Comm comm,MPI_Status*statuses)-阻塞等待,只在在MPI系统探测到符合source/tag条件的消息时才返回-source/tag可以取MPI_ANY_SOURCE/MPI_ANY_TAG-返回的status与MPI_Recv的status完全相同-为接收消息前即可对接收消息进行探测,进而决定如何接收该消息,消息探测(阻塞型),非阻塞式点对点通信,Int MPI_Iprobe(int sourse,int tag,MPI_Comm comm,int*flag,MPI_Status*statuses)-函数调用后即返回-当在MPI探测到
46、符合source/tag条件的消息时,flag=true-若flag=true,返回的status与MPI_Recv的status完全相同,若flag=false,则对status不作定义-source/tag可以取MPI_ANY_SOURCE/MPI_ANY_TAG,消息探测(非阻塞型),非阻塞式点对点通信,Int MPI_Request_free(MPI_Request*request)-调用MPI_Wait/Test可间接释放完成的通信请求,此函数则直接释放通信请求及所占内空间-如果通信尚未完成,则阻塞等待,并完成释放后返回-该函数返回,通信请求request被设置成MPI_REQUES
47、T_NULL,通信请求的释放(阻塞型),非阻塞式点对点通信,Int MPI_Cancel(MPI_Request*request)-MPI_Cancel取消已调用的非阻塞通信,用此命令来解释非阻塞操作所占用的资源-命令调用后立刻返回,但调用并不意味相应的通信被取消。该操作调用时,若相应非阻塞通信已经开始,它会正常完成,不受影响;若没有开始,则释放通信占用资源,该通信被取消-即使调用取消操作,也需等待、查询函数来释放该非阻塞通信的请求,通信请求的取消(非阻塞型),非阻塞式点对点通信,Int MPI_Test_cancelled(MPI_Status*request,int*flag)-函数调用后立即返回-如果一个非阻塞通信已经被执行了取消操作,则该通信的MPI_Wait和MPI_Test将释放相应的通信对象,并且在返回结果status中指明该通信是否被取消-如果MPI_Test_cancelled返回结果flag=true,则表明此通信已经被成功取消,否则该通信还没有被取消,检测一个通信操作是否被取消(非阻塞型),