为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

MPI培训教程_cao

2012-06-06 50页 ppt 851KB 38阅读

用户头像

is_458029

暂无简介

举报
MPI培训教程_caonull MPI 教程 MPI 教程第一章并行编程简介第一章并行编程简介1.1 并行计算机体系结构null分布存储系统的主要特点 系统通过互连网络将多个处理机连接起来,每个处理机均有自己的局部存储器,所有的局部存储器就构成了整个地址空间; 整个地址空间有局部和全局两种编址方式,全局编址方式是指系统的所有局部存储器统一编址,用户程序空间是一个统一的全局的地址空间,其中远程存储器的访问与局部存储器的访问一样用指令来完成,其指令地址由处理器号和局部存储器地址所组成; 局部编址方式是系统中各局部存储器单独编址,用户程序空间是多地...
MPI培训教程_cao
null MPI MPI 教程第一章并行编程简介第一章并行编程简介1.1 并行计算机体系结构null分布存储系统的主要特点 系统通过互连网络将多个处理机连接起来,每个处理机均有自己的局部存储器,所有的局部存储器就构成了整个地址空间; 整个地址空间有局部和全局两种编址方式,全局编址方式是指系统的所有局部存储器统一编址,用户程序空间是一个统一的全局的地址空间,其中远程存储器的访问与局部存储器的访问一样用指令来完成,其指令地址由处理器号和局部存储器地址所组成; 局部编址方式是系统中各局部存储器单独编址,用户程序空间是多地址空间,远程存储器的访问要通过调用消息传递库程序来实现的。null1.2 并行编程模型null1.3 并行语言HPF 、OpenMP 具体由编译器负责数据分发、计算和通信 MPI null1.4并行程序关键负载平衡 减少通讯 通信和计算交叠null并行计算执行时间计算方法,在不考虑内存开销对计算时间的影响时,其计算公式如下: 式中 ——一个PE上的执行时间 ——并行部分的执行时间 ——通讯所耗费的时间 ——用一个PE执行时不可并行化部分所耗时间占的百分比 null第二章 MPI简介第二章 MPI简介 在消息传递库方法的并行编程中,一组进程所执行的程序是用标准串行语言书写的代码加上用于消息接收和发送的库函数调用。其中,MPI(Message Passing Interface )是1994年5月发布的一种消息传递接口。它实际上是一个消息传递函数库的标准说明,吸取了众多消息传递系统的优点,是目前国际上最流行的并行编程环境之一。nullMPI优点: 1. 具有可移植性 2. 易用性; 3. 有完备的异步通信功能; 4. 有正式和详细的精确定义。null 在基于MPI编程模型中,计算是由一个或多个彼此通过调用库函数进行消息收、发通信的进程所组成。在绝大部分MPI实现中,一组固定的进程在程序初始化时生成,一般情况下,一个处理器只生成一个进程。这些进程可以执行相同或不同的程序(相应地称为单程序多数据(SPMD)或多程序多数据(MPMD)模式)。进程间的通信可以是点到点的,也可以是集合的。 MPI只是为程序员提供一个并行环境库,程序员通过调用MPI的库程序来达到程序员所要达到的并行目的,MPI提供C语言和Fortran语言接口。 null MPI是个复杂的系统,它包含了129个函数(根据1994年发布的MPI标准)。事实上,1997年修订的标准,称之为MPI-2,已超过200多个,目前最常用的也有约30个。然而我们可以只使用其中的6个最基本的函数就能编写一个完整的MPI程序去求解很多问题。这6个基本函数,包括启动和结束MPI环境,识别进程以及发送和接收消息: nullMPI_INIT: 启动MPI环境 MPI_FIANLIZE: 结束MPI环境 MPI_COMM_SIZE: 确定进程数 MPI_COMM_RANK: 确定自己的进程标识符 MPI_SEND: 发送一条消息 MPI_RECV: 接收一条消息2.1 简单例子2.1 简单例子#include “mpi.h” main(int argc, char **argv) { int myrank,i,j,k; MPI_Status status; char msg[20]; MPI_Init(&argc,&argv); MPI_Comm_rank(MPI_COMM_WORLD,&myrank); if(myrank == 0){ strcpy(msg,”Hello there”); MPI_Send(msg,strlen(msg) + 1,MPI_CHAR,1,99,MPI_COMM_WORLD); }else if(myrank ==1){ MPI_Recv(msg,20,MPI_CHAR,0,99,MPI_COMM_WORLD,&status); printf(“Receive message = %s\n”,msg); } MPI_Finalize(); }2.2 相关名词2.2 相关名词分布式内存 消息传输 进程 消息传递库 发送 / 接收 同步 / 异步 阻塞通讯 非阻塞通讯 应用程序缓冲区 系统缓冲区2.2.1 分布式内存2.2.1 分布式内存每个处理器都有自己的私有存储空间,数据从一个处理器到另一个处理器只有通过网络来传输,而共享存储中的多个处理器可同时访问同一内存单元。分布式系统的示意图如下:2.2.2 消息传输2.2.2 消息传输消息传输是消息数据从一个处理器的内存拷贝到另一个处理器内存的方法。在分布式存储系统中,数据通常是以消息包的形式通过网络从一个处理器发送到另一个处理器。在消息包中,包含了消息头控制信息及消息体数据信息两部分。2.2.3 进程2.2.3 进程进程是运行在一个处理器上的一个程序,多个进程可运行在同一个处理器上。在消息传递系统中,即使是在同一个处理器中运行的多个进程,他们之间的数据通讯也是通过消息传输来实现的。为了提高效率,在消息传递系统中,一般一个处理器只运行一个进程。2.2.4 消息传递库2.2.4 消息传递库可连接到用户应用程序中实现消息发送、消息接收以及其他消息传递操作的一组函数的集合。2.2.5 发送/接收 2.2.5 发送/接收 消息通信包括数据传输从一个进程(发送)到另一个进程(接收)。这就要求两个进程协作完成消息发送和接收过程,发送进程一般要求指定发送数据的源、数据长度、数据类型及目的地,而接收操作也要求指定相应的操作与发送相匹配。2.2.6 同步/异步 2.2.6 同步/异步 同步发送操作只有等到消息被接收进程安全接收后才完成,而异步发送操作完成后消息不一定被接收进程接收。2.2.7 阻塞通信2.2.7 阻塞通信阻塞通信的调用是否完成要依靠某些“事件”:对于阻塞发送,数据必须成功的发送或被拷贝到系统缓冲区,使得该数据缓冲区可被重新使用;对于阻塞接收,数据必须保证正确接收到本地缓冲区。2.2.8 非阻塞通信2.2.8 非阻塞通信非阻塞通信不等待任何通信事件就可以完成,它不保证数据已正确发送或接收。发送或接收的数据也许在源方,也许正在网上,也许已经到目的方。 2.2.9 应用程序缓冲区2.2.9 应用程序缓冲区在用户应用程序中定义的用于保存发送和接收数据的地址空间。2.2.10 系统缓冲区2.2.10 系统缓冲区保留消息的系统空间。在异步通讯的条件下,一般需要把数据从应用程序缓冲区中拷贝到系统缓冲区,保证用户数据不被覆盖。 2.3 MPI编程环境2.3 MPI编程环境头文件 调用格式 一般程序结构 通信因子和组 秩2.3.1 头文件2.3.1 头文件MPI程序要求:所有包含MPI调用的程序文件头应加入:2.3.2 MPI函数调用格式2.3.2 MPI函数调用格式C程序区分大小写、Fortran程序不区分大小写:null 在C语言描述中,函数名均冠以MPI前缀,且其首字母需大写。返回的状态值是整数;成功完成的返回代码是MPI_SUCCESS;失败时也会定义一组错误代码。编译时的常数均须大写且被定义在文件mpi.h中,mpi.h在任何需调用MPI的程序中必须被包含进来。 在Fortran语言描述中,函数名也冠以MPI前缀,且必须大写。函数返回代码由一个附加的整数变量表示之;成功完成的返回代码是MPI_SUCCESS;失败时也会定义一组错误代码。编译时的常数均须大写且被定义在文件mpif.h中,它在任何需调用MPI的程序中必须被包含进来。 2.3.3 MPI程序的一般结构2.3.3 MPI程序的一般结构包含MPI头文件初始化MPI环境消息交换处理及计算等退出MPI环境2.3.4 通信因子和组2.3.4 通信因子和组MPI通过指定通信因子和组来完成各个进程间得通信,大多数MPI调用要求加入通信因子这个参数。MPI_COMM_WORLD通信因子是在MPI环境初始化过程中创建,它指明所有的进程都参与计算。详细的用法下面再介绍。2.3.5 秩(rank)2.3.5 秩(rank)在一个通信因子中,每个进程都有一个唯一的整数标识符,该标识符在MPI初始化时创建,有时也称作“进程ID”,秩是从0开始的连续整数。在用户程序中,经常用秩来判断程序的运行方向。如:if (rank ==0) { 第0进程运行的程序段 } else if(rank == 1) { 第1进程运行的程序段 }第三章 MPI环境管理调用第三章 MPI环境管理调用本章主要介绍进入MPI环境、退出MPI环境、读取环境变量及读取时钟的函数调用。3.1 函数调用3.1 函数调用MPI_Init MPI_Comm_size MPI_Comm_rank MPI_Abort MPI_Get_processor_name MPI_Initialized MPI_Wtime MPI_Wtick MPI_Finalize3.1.1 MPI_Init()3.1.1 MPI_Init()MPI的初始化例行函数,用于初始化MPI运行环境。每个MPI程序必须调用这个函数,并且这个函数必须在调用其它MPI函数之前被调用,而且只能调用一次。对于C程序,MPI_Init必须传递所有的命令行参数: Int MPI_Init (int *argc,char *argv) MPI_INIT (ierr) INTEGER ierr 3.1.2 MPI_Finalize()3.1.2 MPI_Finalize()结束MPI执行环境。该函数一旦被应用程序调用时,就不能调用MPI的其它例行函数(包括MPI_Init),用户必须保证在进程调用MPI_Finalize之前把与完成进程有关的所有通信结束。 int MPI_Finalize () MPI_FINALIZE (ierr) INTEGER ierr3.1.3 MPI_Comm_size()3.1.3 MPI_Comm_size()该函数返回与该组通信因子相关的进程数,通常可以根据通信 因子MPI_COMM_WORD来查询用户程序包含的进程数: MPI_Comm_size (comm,size) IN comm 通信因子 OUT size 通信因子为comm的组所包含的总进程数 MPI_Comm_size (MPI_Comm comm,int *size) MPI_COMM_SIZE (comm,size,ierr) INTEGER comm,size,ierr3.1.4 MPI_Comm_rank()3.1.4 MPI_Comm_rank()该函数返回该进程在指定通信因子中的秩(0 ~ 进程数-1),一个进程在不同通信因子中的秩可能不同: MPI_Comm_rank (comm, rank) IN comm 通信因子 OUT rank 秩 int MPI_Comm_rank (MPI_comm comm,int *rank) MPI_COMM_RANK (comm,rank,ierr) INTEGER comm,rank,ierr 3.1.5 MPI_Abort()3.1.5 MPI_Abort()结束所有与该通信因子相关的进程,但一般来说,调用该函数后,所有的进程都退出,不管该进程是否与该通信因子相关: MPI_Abort (comm,errorcode) MPI_ABORT (comm,errorcode,ierr) 3.1.6 MPI_Wtime()3.1.6 MPI_Wtime()返回调用进程已经执行过的时间,以秒为单位,双精度: MPI_Wtime () MPI_WTIME () 3.2 MPI环境管理例子3.2 MPI环境管理例子C 语言例子 Fortran 语言例子3.2.1 C 语言例子3.2.1 C 语言例子#include "mpi.h” int main(argc,argv) int argc; char *argv[]; { int numtasks, rank, rc; rc = MPI_Init(&argc,&argv); if (rc != 0) { printf ("Error starting MPI program. Terminating.\n"); MPI_Abort(MPI_COMM_WORLD, rc); } MPI_Comm_size(MPI_COMM_WORLD,&numtasks); MPI_Comm_rank(MPI_COMM_WORLD,&rank); printf ("Number of tasks= %d My rank= %d\n", numtasks,rank); /******* do some work *******/ MPI_Finalize(); }3.2.2 Fortran语言例子3.2.2 Fortran语言例子program simple include 'mpif.h' integer numtasks, rank, ierr, rc call MPI_INIT(ierr) if (ierr .ne. 0) then print *,'Error starting MPI program. Terminating.' call MPI_ABORT(MPI_COMM_WORLD, rc, ierr) end if call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, numtasks, ierr) print *, 'Number of tasks=',numtasks,' My rank=',rank C ****** do some work ****** call MPI_FINALIZE(ierr) end第四章 点对点通信函数第四章 点对点通信函数 MPI的基本通信机制是在一对进程(一方发送、另一方接收)之间传递数据,我们称之为点对点通信(Point-to-Point Communication),它是MPI中比较复杂的一部分, 几乎所有的MPI结构都是围绕着点对点操作。其数据传送有阻塞和非阻塞两组机制:对于阻塞方式,它必须等到消息从本地送出之后才可以执行后续的语句,保证了缓冲区等资源的可再用性;对于非阻塞方式,它不须等到消息从本地送出就可以执行后续的语句,从而允许通信和计算的重叠,但非阻塞调用的返回并不保证资源的可再用性。 null标准模式: 阻塞(标准)发送 MPI_SEND; 阻塞(标准)接收 MPI_RECV; 非阻塞(标准)发送 MPI_ISEND; 非阻塞(标准)接收 MPI_IRECV。SR1null缓冲区模式: 阻塞缓冲发送 MPI_BSEND; 非阻塞缓冲发送 MPI_IBSEND。SR1缓冲区2null同步模式: 阻塞同步发送 MPI_SSEND; 非阻塞同步发送 MPI_ISSEND 。 SR1 2 3null就绪模式: 阻塞就绪发送 MPI_RSEND; 非阻塞就绪发送 MPI_IRSEND ; SR1 2null 在标准通信模式中,MPI根据当前的状况选取其它三种模式或用户定义的其它模式; 缓冲区模式在相匹配的接收未开始的情况下,总是将送出的消息放在缓冲区内,这样发送者可以很快地继续计算,然后由系统处理放在缓冲区中的消息,但这不仅占用内存,而且多用了一次内存拷贝; 在同步模式中,MPI必须保证接收者执行到某一点,这样接收者是必须有确认信息的; 在就绪模式下,系统默认与其相匹配的接收已经调用。 4.1 参数说明4.1 参数说明MPI消息传递函数参数 缓冲区(buffer) 数据个数(count) 数据类型(type) 目的地 (dest) 源 (source) 标识符(tag) 通信因子(comm) 状态(status) 请求(request)4.1.1 MPI消息传递函数参数4.1.1 MPI消息传递函数参数MPI点对点通信函数的参数格式一般如下所示:4.1.2 缓冲区(buffer)4.1.2 缓冲区(buffer)指应用程序定义地用于发送或接收数据的消息缓冲区。 4.1.3 数据个数(count)4.1.3 数据个数(count)指发送或接收指定数据类型的个数。 数据类型的长度 * 数据个数的值为用户实际传递的消息长度。 4.1.4 数据类型(type)4.1.4 数据类型(type)MPI定义了一些缺省的数据类型,用户也可以根据需要建立自己的数据类型,其中MPI_BYTE 和 MPI_PACKED与C或Fortran语言的类型不对应: null续上页nullMPI Data Type (Fortran Bindings)nullcontinuenull 数据类型匹配 消息传送包含下列三个阶段: 1) 消息装配:从发送缓冲区拷贝出数据并汇编成一个消息。 2) 消息传递:消息从发方传送到收方。 3)消息拆卸:从输入消息拷贝数据并反汇编入接收缓冲区。 null发方和收方指定匹配的类型: CALL MPI_COMM_RANK(comm,rank,ierr) IF (rank .EQ. 0) THEN CALL MPI_SEND( a(1),10,MPI_REAL,1,tag,comm,ierr) ELSE IF (rank .EQ. 1) THEN CALL MPI_RECV( b(1),15,MPI_REAL,0,tag,comm,status,ierr) END IF 4.1.5 目的地 (dest)4.1.5 目的地 (dest)发送进程指定的接收该消息的目的进程,也就是接收进程的秩。4.1.6 源 (source)4.1.6 源 (source)接收进程指定的发送该消息的源进程,也就是发送进程的秩。如果该值为MPI_ANY_SOURCE表示接收任意源进程发来的消息。 4.1.7 标识符(tag)4.1.7 标识符(tag)由程序员指定地为标识一个消息的唯一非负整数值(0-32767),发送操作和接收操作的标识符一定要匹配,但对于接收操作来说,如果tag指定为MPI_ANY_TAG则可与任何发送操作的tag相匹配。 4.1.8 通信因子(comm)4.1.8 通信因子(comm)包含源与目的进程的一组上下文相关的进程集合,除非用户自己定义(创建)了新的通信因子,否则一般使用系统预先定义的全局通信因子MPI_COMM_WORLD。 4.1.9 状态(status)4.1.9 状态(status)对于接收操作,包含了接收消息的源进程(source)和消息的标识符(tag)。在C程序中,这个参数是指向MPI_Status结构的指针(如:status.MPI_SOURCE、status.MPI_TAG);在Fortran程序中,这个参数是大小为MPI_STATUS_SIZE的整数矩阵(如:status(MPI_SOURCE)、status(MPI_TAG))。另外,实际接收到的消息长度可以通过MPI_Get_count()函数从该参数中得到。 4.1.10 请求(request) 4.1.10 请求(request)这个参数用于非阻塞发送和非阻塞接收操作。由于非阻塞操作返回后,消息实际上还没有完成到达真正发送或接收,因此用户可以根据该变量调用其它函数完成消息的实际发送和接收。在C程序中,这个参数是指向MPI_Request结构的指针;在Fortran程序中,这个参数是一个整数。4.2 阻塞消息通信函数4.2 阻塞消息通信函数MPI_Send、MPI_Recv、MPI_Ssend、MPI_Bsend、MPI_Rsend MPI_Buffer_attach、MPI_Buffer_detach MPI_Sendrecv MPI_Wait、MPI_Waitany、MPI_Waitall、MPI_Waitsome MPI_Probe 4.2.1 MPI_Send()4.2.1 MPI_Send()该函数是最基本的阻塞发送函数。当函数返回时,应用程序的发送缓冲区空闲,可以继续使用。 MPI_SEND(buf,count,datatype,dest,fag,comm) IN buf 发送缓冲区的初始地址 IN count 发送项数 IN datatype 每项数据类型 IN dest 目标的进程序号 IN tag 消息标志 IN comm 通信因子 null int MPI_Send(void *buf, int count, MPI_Datatype datatype, int dest,int tag, MPI_Comm comm) MPI_SEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, TERROR) BUF(*) INTEGER COUNT, DATATYPE, DEST, TAG, COMM, IERROR 4.2.2 MPI_Recv()4.2.2 MPI_Recv()阻塞接收消息,直到该消息到达本进程的接收缓冲区后才返回。 MPI_RECV(buf,count,datatype,source,tag,comm,status) OUT buf 接收缓冲区的初始地址 IN count 接收最多的项数 IN datatype 每一项的数据类型 IN source 源的进程序号 IN tag 消息标志 IN comm 通信因子 IN status 返回状态 null int recv(void * buf,int count,MPI_Datatype datatype,int source,int tag,MPI_Comm comm,MPI_Status *status) MPI_RECV(BUF,COUNT,DATATYPE,SOURCE,TAG,COMM,STATUS,IERROR) BUF(*) INTEGER COUNT,DATATYPE,SOURCE,TAG,COMM, STATUS(MPI_STATUS_SIZE),IERROR null 在C语言中,状态是MPI_Status 类型的一种结构,它包含MPI_SOURCE、MPI_TAG和MPI_ERROR 3个字段;这种结构还可以包含不同的字段。 status.MPI_SOURCE 发送数据的进程标识 status.MPI_TAG 发送数据的消息标识 status.MPI_ERROR 接收操作返回的错误代码 在Fortran语言中,状态是长度为MPI_STATUS_SIZE的一个整型数组。MPI_SOURCE、MPI_TAG和MPI_ERROR 3个常数是存储源、标志和错误字段项的系数。 status(MPI_SOURCE) 发送数据的进程标识 status(MPI_TAG ) 发送数据的消息标识 status(MPI_ERROR) 接收操作返回的错误代码 null4.3 阻塞消息传递例子4.3 阻塞消息传递例子C 语言例子 Fortran 语言例子4.3.1 C 语言例子4.3.1 C 语言例子#include "mpi.h" #include int main(argc,argv) int argc; char *argv[]; { int numtasks, rank, dest, source, rc, tag=1; char inmsg, outmsg='x'; MPI_Status Stat; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD, &numtasks); MPI_Comm_rank(MPI_COMM_WORLD, &rank); 续上页续上页 if (rank == 0) { dest = 1; source = 1; rc = MPI_Send(&outmsg, 1, MPI_CHAR, dest, tag, MPI_COMM_WORLD); rc = MPI_Recv(&inmsg, 1, MPI_CHAR, source, tag, MPI_COMM_WORLD, &Stat); } else if (rank == 1) { dest = 0; source = 0; rc = MPI_Recv(&inmsg, 1, MPI_CHAR, source, tag, MPI_COMM_WORLD, &Stat); rc = MPI_Send(&outmsg, 1, MPI_CHAR, dest, tag, MPI_COMM_WORLD); } MPI_Finalize(); }4.3.2 Fortran 语言例子4.3.2 Fortran 语言例子 program ping include 'mpif.h' integer numtasks, rank, dest, source, tag, ierr integer stat(MPI_STATUS_SIZE) character inmsg, outmsg tag = 1 call MPI_INIT(ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, numtasks, ierr) 续上页续上页if (rank .eq. 0) then dest = 1 source = 1 outmsg = 'x' call MPI_SEND(outmsg, 1, MPI_CHARACTER, dest, tag,, & MPI_COMM_WORLD, ierr) call MPI_RECV(inmsg, 1, MPI_CHARACTER, source, tag, & MPI_COMM_WORLD, stat, ierr) else if (rank .eq. 1) then dest = 0 source = 0 call MPI_RECV(inmsg, 1, MPI_CHARACTER, source, tag, & MPI_COMM_WORLD, stat, err) call MPI_SEND(outmsg, 1, MPI_CHARACTER, dest, tag, & MPI_COMM_WORLD, err) endif call MPI_FINALIZE(ierr) end4.4 阻塞消息的安全编程4.4 阻塞消息的安全编程安全的消息交换 试图交换消息 取决于缓存的消息交换 nullIF (rank .EQ. 0) THEN CALL MPI_SEND( sendbuf,count,MPI_REAL,1,tag,comm,ierr) CALL MPI_RECV( recvbuf,count,MPI_REAL,1,tag,comm,status,ierr) ELSE IF (rank .EQ. 1) THEN CALL MPI_RECV( recvbuf,count,MPI_REAL,0,tag,comm,status,ierr) CALL MPI_SEND( sendbuf,count,MPI_REAL,0,tag,comm,ierr) END IF 安全的消息交换nullIF (rank .EQ. 0) THEN CALL MPI_RECV( recvbuf,count,MPI_REAL,1,tag,comm,status,ierr) CALL MPI_SEND( sendbuf,count,MPI_REAL,1,tag,comm,ierr) ELSE IF (rank .EQ. 1) THEN CALL MPI_ RECV ( sendbuf,count,MPI_REAL,0,tag,comm,ierr) CALL MPI_ SEND( recvbuf,count,MPI_REAL,0,tag,comm,status,ierr) END IF 试图交换消息nullIF (rank .EQ. 0) THEN CALL MPI_SEND( sendbuf,count,MPI_REAL,1,tag, comm,ierr) CALL MPI_RECV( recvbuf,count,MPI_REAL,1,tag,comm,status,ierr) ELSE IF (rank .EQ. 1) THEN CALL MPI_SEND( sendbuf,count,MPI_REAL,0,tag,comm,ierr) CALL MPI_RECV( recvbuf,count,MPI_REAL,0,tag,comm,status,ierr) END IF 取决于缓存的消息交换4.5 非阻塞消息通信函数4.5 非阻塞消息通信函数MPI_Isend MPI_Irecv MPI_Issend MPI_Ibsend MPI_Irsend MPI_Test 、MPI_Testany 、MPI_Testall 、MPI_Testsome MPI_Iprobe 4.5.1 MPI_Isend()4.5.1 MPI_Isend()非阻塞发送,该函数调用后立即返回,并回送一个发送消息句柄,发送的消息还在应用程序缓冲区中,直到MPI_Wait 或MPI_Test函数等到或测试到消息已经完成发送后,应用程序才能再使用该发送缓冲区: MPI_ISEND(buf,count,datatype,dest,tag,comm,reguest) IN buf 发送缓冲区的起始地址 IN count 发送缓冲区的项数 IN datatype 每个发送缓冲区项的数据类型 IN dest 目标的进程序号 IN tag 消息标志 IN comm 通信因子 OUT reguest 请求处理续上页续上页 int MPI_Isend(void* buf, int count, MPI Datatype datatype, int dest, int tag, MPI Comm comm,MPI Request *request) MPI_ISEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERROR) BUF(*) INTEGER COUNT, DATATYPE, DEST, TAG, COMM, REQUEST, IERROR 4.5.2 MPI_Irecv()4.5.2 MPI_Irecv()非阻塞接收,该调用返回后,所要接收的消息未必到本地接收缓冲区中,直到完成MPI_Wait 或MPI_Test函数调用后,该接收缓冲区的消息才有效: MPI_IRECV (buf, count, datatype, source, tag, comm, request) OUT buf 接收缓冲区的起始地址 IN count 接收缓冲区的项数 IN datatype 每个接收缓冲区项的数据类型 IN source 源的进程序号 IN tag 消息标志 IN comm 通信因子 OUT request 请求处理 续上页续上页 int MPI_Irecv(void* buf, int count, MPI Datatype datatype, int source, int tag, MPI Comm comm, MPI Request *request) MPI_IRECV(BUF, COUNT, DATATYPE, SOURCE, TAG, COMM, REQUEST, IERROR) BUF(*) INTEGER COUNT, DATATYPE, SOURCE, TAG, COMM, REQUEST, IERROR null 函数MPI_WAIT和MPI_TEST用来完成无阻塞发送和接收。发送完成指出现在发方可以自由存取发送缓冲区。接收完成指出接收缓冲区包含这种消息,收方可以自由存取接收缓冲区,并设置状态目标。 MPI_WAIT(request, status) INOUT request 非阻塞通信对象 OUT status 状态返回 MPI_TEST(request, flag,status) INOUT request 非阻塞通信对象 OUT flag 操作是否完成标志 OUT status 状态返回   4.5.3 完成操作4.6 非阻塞消息传递例子4.6 非阻塞消息传递例子C 语言例子 Fortran 语言例子4.6.1 C语言例子4.6.1 C语言例子#include "mpi.h" #include int main(argc,argv) int argc; char *argv[]; { int numtasks, rank, next, prev, buf[2], tag1=1, tag2=2; MPI_Request reqs[4]; MPI_Status stats[4]; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD, &numtasks); MPI_Comm_rank(MPI_COMM_WORLD, &rank);续上页续上页 prev = rank-1; next = rank+1; if (rank == 0) prev = numtasks - 1; if (rank == (numtasks - 1)) next = 0; MPI_Irecv(&buf[0], 1, MPI_INT, prev, tag1, MPI_COMM_WORLD, &reqs[0]); MPI_Irecv(&buf[1], 1, MPI_INT, next, tag2, MPI_COMM_WORLD, &reqs[1]); MPI_Isend(&rank, 1, MPI_INT, prev, tag2, MPI_COMM_WORLD, &reqs[2]); MPI_Isend(&rank, 1, MPI_INT, next, tag1, MPI_COMM_WORLD, &reqs[3]); MPI_Waitall(4, reqs, stats); MPI_Finalize(); }4.6.2 Fortran语言例子4.6.2 Fortran语言例子 program ringtopo include 'mpif.h' integer numtasks, rank, next, prev, buf(2), tag1, tag2, ierr integer stats(MPI_STATUS_SIZE,4), reqs(4) tag1 = 1 tag2 = 2 call MPI_INIT(ierr) call MPI_COMM_RANK(MPI_COMM_WORLD, rank, ierr) call MPI_COMM_SIZE(MPI_COMM_WORLD, numtasks, ierr) prev = rank - 1 next = rank + 1 if (rank .eq. 0) then prev = numtasks - 1 endif续上页续上页 if (rank .eq. numtasks - 1) then next = 0 endif call MPI_IRECV(buf(1), 1, MPI_INTEGER, prev, tag1, & MPI_COMM_WORLD, reqs(1), ierr) call MPI_IRECV(buf(2), 1, MPI_INTEGER, next, tag2, & MPI_COMM_WORLD, reqs(2), ierr) call MPI_ISEND(rank, 1, MPI_INTEGER, prev, tag2, & MPI_COMM_WORLD, reqs(3), ierr) call MPI_ISEND(rank, 1, MPI_INTEGER, next, tag1, & MPI_COMM_WORLD, reqs(4), ierr) call MPI_WAITALL(4, reqs, stats, ierr); call MPI_FINALIZE(ierr) end4.7 通信模式4.7 通信模式标准模式 缓冲模式 同步模式 预备模式4.7.1 缓存模式4.7.1 缓存模式缓存模式: 直接对通信缓存区进行申请、使用和释放 MPI_BSEND(buf,count,datatype,dest,tag,comm) IN buf 发送缓冲区的初始地址 IN count 发送缓冲区中的项数 IN datatype 每个发送缓冲区项的数据类型 IN dest 目的地的进程号 IN tag 消息标记 IN comm 通信因子 int MPI_Bsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag,MPI_Comm comm) MPI_BSEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, IERROR) BUF(*) INTEGER COUNT, DATATYPE, DEST, TAG, COMM, IERROR null缓存通信模式4.7.2 同步模式4.7.2 同步模式 同步方式的发送不管是否已投寄匹配接收的消息都可以被启动。但是,只有当投寄匹配接收的消息,并且接收操作已开始接收同步发送发来的消息时,同步发送才会成功地完成 同步通信模式null MPI_SSEND(buf,count,datatype,dest,tag,comm) IN buf 发送缓冲区的初始地址 IN count 发送缓冲区中的项数 IN datatype 每个发送缓冲区项的数据类型 IN dest 目的地的进程号 IN tag 消息标记 IN comm 通信因子 int MPI_Bsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag,MPI_Comm comm) MPI_BSEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, IERROR) BUF(*) INTEGER COUNT, DATATYPE, DEST, TAG, COMM, IERROR 4.7.3 预备模式4.7.3 预备模式预备方式 消息的发送仅当已投寄匹配接收消息之后 才被启动。否则,操作是错误的 。预备通信模式4.7.3 预备模式4.7.3 预备模式 MPI_RSEND(buf,count,datatype,dest,tag,comm) IN buf 发送缓冲区的初始地址 IN count 发送缓冲区中的项数 IN datatype 每个发送缓冲区项的数据类型 IN dest 目的地的进程号 IN tag 消息标记 IN comm 通信因子 int MPI_Rsend(void* buf, int count, MPI_Datatype datatype, int dest, int tag,MPI_Comm comm) MPI_RSEND(BUF, COUNT, DATATYPE, DEST, TAG, COMM, IERROR) BUF(*) INTEGER COUNT, DATATYPE, DEST, TAG, COMM, IERROR 第五章 集合通信函数第五章 集合通信函数集合通信是包含在通信因子中的所有进程都参加操作,当通信因子为MPI_COMM_WORLD时,应用程序中所有进程都参加。 集合操作的三种类型: 同步(barrier):集合中所有进程都到达后,每个进程再接着运行; 数据传递:广播(broadcast)、分散(scatter)、收集(gather)、全部到全部(alltoall); 规约(reduction):集合中的其中一个进程收集所有进程的数据并计算(如:求最大值、求最小值、加、乘等);接上页接上页集合操作是阻塞的。 集合操作不带标识符(tag)参数。 只支持MPI标准的数据类型,不支持派生数据类型。 5.1 集合通信函数5.1 集合通信函数MPI_Barrier、MPI_Bcast、MPI_Scatter MPI_Gather、MPI_Allgather MPI_Reduce、MPI_Allreduce MPI_Reduce_scatter MPI_Alltoall MPI_Scan5.1.1 MPI_Barrier()5.1.1 MPI_Barrier()在组中建立一个同步栅栏。当每个进程都到达MPI_Barrier调用后,程序才接着往下执行: MPI_Barrier (comm) MPI_BARRIER (comm,ierr) Comm参数为包含所有需要参加同步的进程的通信因子。5.1.2 MPI_Bcast()5.1.2 MPI_Bcast()从指定的一个跟进程中把数据广播发送给组中的所有其它进程: MPI_Bcast (*buffer,count,datatype,root,comm) MPI_BCAST (buffer,count,datatype,root,comm, ierr) null接上页5.1.3 MPI_Scatter()5.1.3 MPI_Scatter()把指定的跟进程中的数据分散发送给组中的所有进程(包括自己): MPI_Scatter (*sendbuf,sendcnt,sendtype, *recvbuf, recvcnt,recvtype,root,comm) MPI_SCATTER (sendbuf,sendcnt,sendtype, recvbuf, recvcnt,recvtype,root,comm,ierr) null接上页5.1.4 MPI_Gather()5.1.4 MPI_Gather()在组中指定一个进程收集组中所有进程发送来的消息,这个函数操作与MPI_Scatter函数操作相反: MPI_Gather (*sendbuf,sendcnt,sendtype, *recvbuf, recvcount,recvtype,root,comm) MPI_GATHER (sen
/
本文档为【MPI培训教程_cao】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索