1、1Copyright 2010,Elsevier Inc.All rights ReservedChapter 3用MPI进行分布式内存编程An Introduction to Parallel ProgrammingPeter Pacheco2Copyright 2010,Elsevier Inc.All rights ReservedRoadmapn编写第一个MPI程序.n常见的MPI函数.n用MPI来实现梯形积分法.n集合通信.nMPI的派生数据类型.nMPI程序的性能评估.n并行排序算法.nMPI程序的安全性.#Chapter Subtitle3分布式内存系统分布式内存系统Copyri
2、ght 2010,Elsevier Inc.All rights Reserved4共享内存系统共享内存系统Copyright 2010,Elsevier Inc.All rights Reserved5进程进程进程是一个程序,同时包含它的执行环境(内存、寄存器、程序计数器等),是操作系统中独立存在的可执行的基本程序单位。通俗理解:串行应用程序编译形成的可执行代码,分为“指令”和“数据”两个部分,并在程序执行时“独立地申请和占有”内存空间,且所有计算均局限于该内存空间。6正在微机上运行的进程正在微机上运行的进程7单机内的多个进程单机内的多个进程多个进程可以同时存在于单机内同一操作系统:由操作系
3、统负责调度分时共享处理机资源(CPU、内存、存储、外设等)。进程间相互独立(内存空间不相交):在操作系统调度下各自独立地运行,例如多个串行应用程序在同一台计算机中运行。进程1内存进程28最基本的消息传递操作:发送消息(send)、接受消息(r e c e i v e)、进 程 同 步(b a r r i e r)、规 约(reduction)。消息传递的实现:共享内存或信号量,用户不必关心。进程间可以相互交换信息:例如数据交换、同步等待,消息是这些交换信息的基本单位,消息传递是指这些信息在进程间的相互交换,是实现进程间通信的唯一方式。9同时运行于单机上的多个进程同时运行于单机上的多个进程10进
4、程1内存进程2并行程序的单机运行方式并行程序的单机运行方式进程3进程411消息传递并行程序设计消息传递并行程序设计MPICopyright 2010,Elsevier Inc.All rights Reservedn消息传递并行程序设计n用户必须通过显式地发送和接收消息来实现处理机间的数据交换n每个并行进程均有自己独立的地址空间,相互之间访问不能直接进行,必须通过显式的消息传递来实现n适用于大规模并行处理机(MPP)和机群(Cluster)12Copyright 2010,Elsevier Inc.All rights Reservedn并行计算粒度大,适合大规模可扩展并行算法n消息传递程序设
5、计要求用户很好地分解问题,组织不同进程间的数据交换,并行计算粒度大,特别适合于大规模可扩展并行算法13什么是什么是MPI?Copyright 2010,Elsevier Inc.All rights ReservednMassage Passing Interface:是消息传递函数库的标准规范,由MPI论坛开发,支持Fortran和C。n一种新的库描述,不是一种语言n共有上百个函数调用接口,在Fortran和C语言中可以直接对这些函数进行调用n是一种标准或规范,而不是特指某一个对它的具体实现nMPI是一种消息传递编程模型,并成为这种编程模型的代表和事实上的标准14为什么要使用为什么要使用MP
6、I?Copyright 2010,Elsevier Inc.All rights Reservedn高可移植性nMPI已在PC机、MS Windows以及所有主要的Unix工作站上和所有主流的并行机上得到实现n使用MPI作消息传递的C或Fortran并行程序可不加改变地在上述平台实现15MPI的发展过程的发展过程Copyright 2010,Elsevier Inc.All rights Reservedn发展的两个阶段n1994年5月完成1.0版n支持C和Fortran77n制定大部分并行功能n1997年4月完成2.0版n动态进程n并行I/On支持Fortran 90和C+16常用的常用的M
7、PI版本版本Copyright 2010,Elsevier Inc.All rights ReservednMPICH n是MPI最流行的非专利实现,由Argonne国家实验室和密西西比州立大学联合开发,具有更好的可移植性n当前最新版本有MPICH 3.2nhttp:/www.mpich.org/nLAMMPIn美国Indiana 大学Open Systems 实验室实现nhttp:/lammps.sandia.govn更多的商业版本MPInHP-MPI,MS-MPI,n所有的版本遵循MPI标准,MPI程序可以不加修改的运行17Hello World!Copyright 2010,Elsevi
8、er Inc.All rights Reserved(a classic)18从简单入手从简单入手Copyright 2010,Elsevier Inc.All rights Reservedn下面我们首先分别以C语言的形式给出一个最简单的MPI并行程序 Hello n该程序在终端打印出Hello World!字样.19识别识别 MPI 进程进程n在并行编程中,常见的是将进程按照非负整数来进行标注.np 个进程被编号为0,1,2,.p-1Copyright 2010,Elsevier Inc.All rights Reserved20第一个第一个 MPI 程序程序Copyright 2010,
9、Elsevier Inc.All rights Reserved21编译,生成编译,生成hello的可执行代码的可执行代码Copyright 2010,Elsevier Inc.All rights Reservedmpicc -g -Wall -o mpi_hello mpi_hello.cC语言编译器的包装脚本打印警告信息源文件创建编译后的输出文件(默认为a.out)加入调试信息22执行执行Copyright 2010,Elsevier Inc.All rights Reservedmpiexec -n mpiexec -n 1 ./mpi_hellompiexec -n 4 ./mpi_
10、hello用1个进程运行程序用4个进程运行程序23ExecutionCopyright 2010,Elsevier Inc.All rights Reservedmpiexec -n 1 ./mpi_hellompiexec -n 4 ./mpi_helloGreetings from process 0 of 1!Greetings from process 0 of 4!Greetings from process 1 of 4!Greetings from process 2 of 4!Greetings from process 3 of 4!243.1.2 MPI 程序程序nC语言.
11、n包含了main函数.n标准头文件 stdio.h,string.h,etc.n包含 mpi.h 头文件.n所有MPI定义的标识符都由字符串“MPI_”开始.n下划线后的第一字母大写。n表示函数名和MPI定义的类型n避免混淆Copyright 2010,Elsevier Inc.All rights Reserved25MPI程序的框架结构程序的框架结构头文件包含MPI库相关变量的声明定义与通信有关的变量程序开始调用MPI初始化函数程序结束调用MPI结束函数 程序体计算与通信调用MPI其它函数26第三部分第五部分第一部分用用C+MPI实现实现hello world!#include mpi.h
12、#include#include void main(int argc,char*argv)int myid,numprocs namelen;char processor_nameMPI_MAX_PROCESSOR_NAME;MPI_Init(&argc,&argv);/*程序初始化*/MPI_Comm_rank(MPI_COMM_WORLD,&myid);/*得到当前进程号*/MPI_Comm_size(MPI_COMM_WORLD,&numprocs);/*得到总的进程数*/MPI_Get_processor_name(processor_name,&namelen);/*得到机器名*/
13、printf(“hello world!Process%d of%d on%sn,myid,numprocs,processor_name);MPI_Finalize();/*结束*/第二部分第四部分27执行结果执行结果28MPI基本调用基本调用 MPI为程序员提供一个并行环境库,程序员通过调用MPI的库程序来达到程序员所要达到的并行目的,可以只使用其中的6个最基本的函数就能编写一个完整的MPI程序去求解很多问题。这6个基本函数,包括启动和结束MPI环境,识别进程以及发送和接收消息:29从理论上说,MPI所有的通信功能可以用它的6个基本的调用来实现:30(1)MPI初始化:通过MPI_Init
14、函数进入MPI环境并完成所有的初始化工作。int MPI_Init(int*argc,char*argv)(2)MPI结束:通过MPI_Finalize函数从MPI环境中退出。int MPI_Finalize(void)31 (3)获取进程的编号:调用MPI_Comm_rank函数获得当前进程在指定通信域中的编号,将自身与其他程序区分。int MPI_Comm_rank(MPI_Comm comm,int*rank)(4)获取指定通信域的进程数:调用MPI_Comm_size函数获取指定通信域的进程个数,确定自身完成任务比例。int MPI_Comm_size(MPI_Comm comm,in
15、t*size)32 (5)消息发送:MPI_Send函数用于发送一个消息到目标进程。int MPI_Send(void*buf,int count,MPI_Datatype dataytpe,int dest,int tag,MPI_Comm comm)(6)消息接受:MPI_Recv函数用于从指定进程接收一个消息 int MPI_Recv(void*buf,int count,MPI_Datatype datatyepe,int source,int tag,MPI_Comm comm,MPI_Status*status)33最简单的最简单的hello.cCopyright 2010,Els
16、evier Inc.All rights Reserved#include#include mpi.h“main(int argc,char*argv)MPI_Init(&argc,&argv);printf(“Hello World!n);MPI_Finalize();34MPIMPI初始化初始化-MPI_INIT-MPI_INITnint MPI_Init(int*argc,char*argv)MPI_INIT(IERROR)nMPI_INIT是MPI程序的第一个调用,完成MPI程序的所有初始化工作。所有的MPI程序的第一条可执行语句都是这条语句n启动MPI环境,标志并行代码的开始n并行代
17、码之前,第一个mpi函数(除MPI_Initialize外)n要求main必须带参数运行。否则出错 Copyright 2010,Elsevier Inc.All rights Reserved35MPIMPI结束结束-MPI_FINALIZE-MPI_FINALIZEnint MPI_Finalize(void)MPI_ Finalize(IERROR)MPI_INIT是MPI程序的最后一个调用,它结束MPI程序的运行,它是MPI程序的最后一条可执行语句,否则程序的运行结果是不可预知的。标志并行代码的结束,结束除主进程外其它进程之后串行代码仍可在主进程(rank=0)上运行(如果必须)Cop
18、yright 2010,Elsevier Inc.All rights Reserved36运行MPI程序 编译:mpicc-o hello 运行:./hello 0 Aborting program!Could not create p4 procgroup.Possible missing fileor program started without mpirun.n运行:mpiexec-np 4 helloHello World!Hello World!Hello World!Hello World!Copyright 2010,Elsevier Inc.All rights Reser
19、ved37HelloHello是如何被执行的?是如何被执行的?nSPMD:Single Program Multiple Data(MIMD)Copyright 2010,Elsevier Inc.All rights Reserved#include#include mpi.h“main(int argc,char*argv)MPI_Init(&argc,&argv);printf(“Hello World!n);MPI_Finalize();#include#include mpi.h“main(int argc,char*argv)MPI_Init(&argc,&argv);printf
20、(“Hello World!n);MPI_Finalize();#include#include mpi.h“main(int argc,char*argv)MPI_Init(&argc,&argv);printf(“Hello World!n);MPI_Finalize();#include#include mpi.h“main(int argc,char*argv)MPI_Init(&argc,&argv);printf(“Hello World!n);MPI_Finalize();#include#include mpi.h“main(int argc,char*argv)MPI_Ini
21、t(&argc,&argv);printf(“Hello World!n);MPI_Finalize();Hello World!Hello World!Hello World!Hello World!38HelloHello程序在单机上的运行方式程序在单机上的运行方式启动程序,开始执行进程0进程1进程2进程3MPI_InitMPI_InitMPI_InitMPI_Initmyid=0myid=1myid=2myid=3numproces=4 numproces=4 numproces=4numproces=4获取机器名并打印获取机器名并打印获取机器名并打印获取机器名并打印MPI_Finali
22、zeMPI_FinalizeMPI_FinalizeMPI_Finalize程序结束39基本框架基本框架Copyright 2010,Elsevier Inc.All rights Reserved40开始写开始写MPIMPI程序程序n写MPI程序时,我们常需要知道以下两个问题的答案:n任务由多少进程来进行并行计算?n我是哪一个进程?Copyright 2010,Elsevier Inc.All rights Reserved41通信子通信子 n一组可以相互发送消息的进程集合.nMPI_Init 在用户启动程序时,定义由用户启动的所有进程所组成的通信子.n称为 MPI_COMM_WORLD.C
23、opyright 2010,Elsevier Inc.All rights Reserved42nMPI提供了下列函数来回答这些问题:n用MPI_Comm_size 获得进程个数p int MPI_Comm_size(MPI_Comm comm,int*comm_sz_p)n用MPI_Comm_rank 获得进程的一个叫my_rank_p的值,该值为0到p-1间的整数,相当于进程的ID int MPI_Comm_rank(MPI_Comm comm,int*my_rank_p)Copyright 2010,Elsevier Inc.All rights Reserved43更新的更新的Hell
24、o World(C语言语言)Copyright 2010,Elsevier Inc.All rights Reserved#include#include mpi.h”main(int argc,char*argv)int myid,numprocs;MPI_Init(&argc,&argv);MPI_Common_rank(MPI_COMMON_WORLD,&myid);MPI_Common_size(MPI_COMMON_WORLD,&numprocs);printf(“I am%d of%d n“,myid,numprocs);MPI_Finalize();44运行结果运行结果nmpic
25、c o hello1 mpiexec-np 4 hello1结果:I am 0 of 4 I am 1 of 4 I am 2 of 4 I am 3 of 4Copyright 2010,Elsevier Inc.All rights Reserved453.1.6 通信通信有消息传递有消息传递greetings(C语言语言)Copyright 2010,Elsevier Inc.All rights Reserved#include#include mpi.h”main(int argc,char*argv)int myid,numprocs,soure;MPI_Status status
26、;char message100;MPI_Init(&argc,&argv);MPI_Common_rank(MPI_COMMON_WORLD,&myid);MPI_Common_size(MPI_COMMON_WORLD,&numprocs);46Copyright 2010,Elsevier Inc.All rights Reserved if(myid!=0)strcpy(message,Hello World!);MPI_Send(message,strlen(message)+1,MPI_CHAR,0,99,MPI_COMM_WORLD);else/*myid=0*/for(sour
27、ce=1;source numprocs;source+)MPI_Recv(message,100,MPI_CHAR,source,99,MPI_COMM_WORLD,&status);printf(%sn,message);MPI_Finalize();/*end main*/47GreetingGreeting执行过程执行过程Copyright 2010,Elsevier Inc.All rights Reserved.Recv().Send().Send().Send().48解剖解剖greetinggreeting程序程序n头文件:mpi.h/mpif.hnint MPI_Init(i
28、nt*argc,char*argv)n通信组/通信子:MPI_COMM_WORLDn一个通信组是一个进程组的集合。所有参与并行计算的进程可以组合为一个或多个通信组n执行MPI_Init后,一个MPI程序的所有进程形成一个缺省的组,这个组被写作MPI_COMM_WORLDn该参数是MPI通信操作函数中必不可少的参数,用于限定参加通信的进程的范围Copyright 2010,Elsevier Inc.All rights Reserved49nint MPI_Comm_size(MPI_Comm comm,int*size)n获得通信组comm中包含的进程数nint MPI_Comm_rank(M
29、PI_Comm comm,int*rank)n得到本进程在通信组中的rank值,即在组中的逻辑编号(从0开始)nint MPI_Finalize()Copyright 2010,Elsevier Inc.All rights Reserved50消息传递消息传递n数据传送同步操作n需要发送方和接受方合作完成Copyright 2010,Elsevier Inc.All rights Reserved51Copyright 2010,Elsevier Inc.All rights ReservednMPI函数的总数虽然庞大,但根据实际编写MPI的经验,常用的MPI调用的个数确实有限。n下面是6个
30、最基本也是最常用的MPI函数nMPI_Init();nMPI_Comm_size()nMPI_Comm_rank()nMPI_Send()nMPI_Recv()nMPI_Finalize()n下面更多的了解下面更多的了解MPI52nint MPI_Send(void*msg_buf_p,int msg_size,MPI_Datatype msg_type,int dest,int tag,MPI_Comm communicator);nIN msg_buf_p 发送缓冲区的起始地址nIN msg_size 要发送信息的元素个数nIN msg_type 发送信息的数据类型nIN dest 目标进
31、程的rank值nIN tag 消息标签nIN communicator 通信组Copyright 2010,Elsevier Inc.All rights Reserved53通信通信Copyright 2010,Elsevier Inc.All rights Reserved54一些预先定义的一些预先定义的MPI数据类型数据类型Copyright 2010,Elsevier Inc.All rights Reserved55nint MPI_Recv(void*msg_buf_p,int buf_size,MPI_Datatype buf_type,int source,int tag,MP
32、I_Comm comminicator,MPI_Status*status_p);nOUT msg_buf_p 发送缓冲区的起始地址nIN buf_size 要发送信息的元素个数nIN buf_type 发送信息的数据类型nIN source 目标进程的rank值nIN tag 消息标签nIN comminicator 通信子nOUT status_p status_p对象,包含实际接收到的消息的有关信息Copyright 2010,Elsevier Inc.All rights Reserved56CommunicationCopyright 2010,Elsevier Inc.All ri
33、ghts Reserved57为什么使用消息标签为什么使用消息标签(Tag)?Copyright 2010,Elsevier Inc.All rights ReservedProcess P:send(A,32,Q)send(B,16,Q)Process Q:recv(X,32,P)recv(Y,16,P)未使用标签 Process P:send(A,32,Q,tag1)send(B,16,Q,tag2)Process Q:recv(X,32,P,tag1)recv(Y,16,P,tag2)使用了标签为了说明为什么要用标签为了说明为什么要用标签,我们我们先来看右面一段没有使用标签先来看右面一段
34、没有使用标签的代码的代码:这段代码打算传送这段代码打算传送A的前的前32个字节进入个字节进入X,传送传送B的前的前16个字个字节进入节进入Y.但是但是,如果消息如果消息B尽管尽管后发送但先到达进程后发送但先到达进程Q,就会被就会被第 一 个第 一 个 r e c v()接 收 在接 收 在 X 中中.使用标签可以避免这个错误使用标签可以避免这个错误.58在消息传递中使用标签在消息传递中使用标签Copyright 2010,Elsevier Inc.All rights Reserved使用标签的另一个原因是可使用标签的另一个原因是可以简化对下列情形的处理:以简化对下列情形的处理:假定有两个客户
35、进程假定有两个客户进程P和和R,每个发送一个服务请求消息每个发送一个服务请求消息给服务进程给服务进程Q.Process P:send(request1,32,Q)Process R:send(request2,32,Q)Process Q:while(true)recv(received_request,32,Any_Process);process received_request;Process P:send(request1,32,Q,tag1)Process R:send(request2,32,Q,tag2)Process Q:while(true)recv(received_req
36、uest,32,Any_Process,Any_Tag,Status);if(Status.Tag=tag1)process received_request in one way;if(Status.Tag=tag2)process received_request in another way;593.1.9 消息匹配消息匹配Copyright 2010,Elsevier Inc.All rights ReservedMPI_Sendsrc=qMPI_Recvdest =rrq60Copyright 2010,Elsevier Inc.All rights Reservedn接收接收buf
37、fer必须至少可以容纳必须至少可以容纳count个由个由datatype参数指明类型的数参数指明类型的数据据.如果接收如果接收buf太小太小,将导致溢出、出错将导致溢出、出错n消息匹配消息匹配n参数匹配dest,tag,comm/source,tag,commnSource=MPI_ANY_SOURCE:接收任意处理器来的数据(任意消息来源).nTag=MPI_ANY_TAG:匹配任意tag值的消息(任意tag消息)n在阻塞式消息传送中不允许在阻塞式消息传送中不允许Source=Dest,否则会导致死锁否则会导致死锁n消息传送被限制在同一个消息传送被限制在同一个communicator.n在在
38、sendsend函数中必须指定唯一的接收者函数中必须指定唯一的接收者61接收消息接收消息n接收者可以在不知道以下信息的情况下接收消息:n消息中的数据量,n消息的发送者,n消息的标签.Copyright 2010,Elsevier Inc.All rights Reserved62status_p参数参数n当使用当使用MPI_ANY_SOURCE或或/和和MPI_ANY_TAG接收消息时如何确接收消息时如何确定消息的来源定消息的来源source 和和tag值?值?n在C中,status.MPI_SOURCE,status.MPI_TAG.nStatus还可用于返回实际接收到消息的长度还可用于返回
39、实际接收到消息的长度nint MPI_Get_count(MPI_Status status_p,n MPI_Datatype type,n int*count.pn )IN status_p 接收操作的返回值.IN type 接收缓冲区中元素的数据类型 OUT count.p 接收消息中的元素个数 Copyright 2010,Elsevier Inc.All rights Reserved63Copyright 2010,Elsevier Inc.All rights ReservedMPI_SOURCEMPI_TAGMPI_ERRORMPI_Status*MPI_Status*statu
40、s;status.MPI_SOURCEstatus.MPI_TAGstatus_p参数参数64How much data am I receiving?Copyright 2010,Elsevier Inc.All rights Reserved65分析分析greetings#include#include mpi.h”main(int argc,char*argv)int numprocs;/*进程数,该变量为各处理器中的同名变量,存储是分布的*/int myid;/*进程ID,存储也是分布的 */MPI_Status status;/*消息接收状态变量,存储也是分布的 */char mes
41、sage100;/*消息buffer,存储也是分布的 */*初始化MPI*/MPI_Init(&argc,&argv);/*该函数被各进程各调用一次,得到自己的进程rank值*/MPI_Common_rank(MPI_COMMON_WORLD,&myid);/*该函数被各进程各调用一次,得到进程数*/MPI_Common_size(MPI_COMMON_WORLD,&numprocs);66分析分析greetings if(myid!=0)/*建立消息*/sprintf(message,Greetings from process%d!,myid);/*发送长度取strlen(message)
42、+1,使0也一同发送出去*/MPI_Send(message,strlen(message)+1,MPI_CHAR,0,99,MPI_COMM_WORLD);else/*myrank=0*/for(source=1;source numprocs;source+)MPI_Recv(message,100,MPI_CHAR,source,99,MPI_COMM_WORLD,&status);printf(%sn,message);/*关闭MPI,标志并行代码段的结束*/MPI_Finalize();/*end main*/67MPI_Send和和MPI_Recv的问题的问题nMPI_Send的精
43、确行为是由MPI实现决定的nMPI_Send可能有不同大小的缓冲区,是缓冲还是阻塞可以由一个消息“截止”大小决定(cutoffs message size)nMPI_Recv总是被阻塞的,直到接收到一条匹配的消息n了解你的执行情况;不要做假设!Copyright 2010,Elsevier Inc.All rights Reserved68用用MPI实现梯形积分法实现梯形积分法Copyright 2010,Elsevier Inc.All rights Reserved69梯形积分法梯形积分法Copyright 2010,Elsevier Inc.All rights Reserved70一个
44、梯形一个梯形Copyright 2010,Elsevier Inc.All rights Reserved71梯形积分法梯形积分法Copyright 2010,Elsevier Inc.All rights Reserved72梯形积分法的串行伪代码梯形积分法的串行伪代码Copyright 2010,Elsevier Inc.All rights Reserved73并行化的梯形积分法并行化的梯形积分法1.将问题的解决方案划分成多个任务。2.在任务间识别出需要的通信信道。3.将任务聚合成复合任务。4.在核上分配复合任务。Copyright 2010,Elsevier Inc.All right
45、s Reserved74并行梯形积分法的任务和通信并行梯形积分法的任务和通信Copyright 2010,Elsevier Inc.All rights Reserved75梯形积分法的并行伪代码梯形积分法的并行伪代码Copyright 2010,Elsevier Inc.All rights Reserved76并行代码并行代码C语言语言Copyright 2010,Elsevier Inc.All rights Reserved77并行代码并行代码C语言语言Copyright 2010,Elsevier Inc.All rights Reserved78Trap函数函数Copyright
46、2010,Elsevier Inc.All rights Reserved793.3 I/O处理处理Copyright 2010,Elsevier Inc.All rights Reserved每个进程只打印一条消息80Running with 6 processesCopyright 2010,Elsevier Inc.All rights Reserved输出不确定性输出不确定性:输出的顺序是无法预测的输出的顺序是无法预测的81输入输入 n大部分的MPI实现只允许MPI_COMM_WORLD 中的0号进程访问标准输入stdin。n0号进程负责读取数据(scanf),并将数据发送给其他进程。
47、Copyright 2010,Elsevier Inc.All rights ReservedGet_input82一个用于读取用户输入的函数一个用于读取用户输入的函数Copyright 2010,Elsevier Inc.All rights Reserved833.4 集合通信集合通信Copyright 2010,Elsevier Inc.All rights Reserved84通信类型通信类型nMPI点对点通信n阻塞型和非阻塞型Blocking,Non-BlockingnMPI集合通信Copyright 2010,Elsevier Inc.All rights Reserved85MP
48、I点对点通信点对点通信n阻塞型通信n阻塞型通信函数需要等待指定的操作实际完成,或所涉及的数据被 MPI 系统安全备份后才返回。nMemory referenced is ready for reuse,Non local operationnMPI_SEND,MPI_RECVCopyright 2010,Elsevier Inc.All rights Reserved86n非阻塞通信n非阻塞型通信函数总是立即返回,实际操作由 MPI 后台进行,需要调用其它函数来查询通信是否完成。nLocal operationn在实际操作完成之前对相关数据区域的操作是不安全的n在有些并行系统上(Communi
49、cation processors),使用非阻塞型函数n可以实现计算与通信的重叠进行nMPI_ISEND,MPI_IRECVCopyright 2010,Elsevier Inc.All rights Reserved87MPI集合通信集合通信n集合通信(collective communication)是一个进程组中的所有进程都参加的全局通信操作。n按照通信方向的不同,集合通信可分为三种类型:n一对多:一个进程向其它所有的进程发送消息,这个负责发送消息的进程叫做Root进程。n多对一:一个进程负责从其它所有的进程接收消息,这个接收的进程也叫做Root进程。n多对多:每一个进程都向其它所有的进
50、程发送或者接收消息。nCopyright 2010,Elsevier Inc.All rights Reserved88n集合通信一般实现三个功能:n通信,同步和计算n通信功能主要完成组内数据的传输 n聚集功能在通信的基础上对给定的数据完成一定的操作 n同步功能实现组内所有进程在执行进度上取得一致 Copyright 2010,Elsevier Inc.All rights Reserved893.4.1 树形结构通信树形结构通信1.第一阶段:(a)1号,3号,5号,7号进程将他们的值分别发送给0号,2号,4号,6号进程。(b)0,2,4和6号进程将接收到的值加到他们自己原有的值上。(c)2号