消息传递并行编程环境MPI.docx
- 文档编号:28727545
- 上传时间:2023-07-19
- 格式:DOCX
- 页数:27
- 大小:27.91KB
消息传递并行编程环境MPI.docx
《消息传递并行编程环境MPI.docx》由会员分享,可在线阅读,更多相关《消息传递并行编程环境MPI.docx(27页珍藏版)》请在冰豆网上搜索。
消息传递并行编程环境MPI
国家973项目高性能计算环境支持讲座
MPI与PETSc
莫则尧
(北京应用物理与计算数学研究所)
日期
内容
8.15
上午
进程与消息传递、
MPI应用现状、
MPI并行程序设计入门、
初步的MPI消息传递函数
下午
作业一、讨论
8.16
上午
作业一讲评、
先进的MPI函数、
并行程序示例2、
MPI的发展
下午
作业二、讨论
8.17
上午
作业二讲评、
并行可扩展科学计算工具箱PETSc介绍
下午
PETSc程序示例
个人介绍
莫则尧,男,汉族,1971年7月生,副研究员:
●1992年国防科技大学应用数学专业本科毕业;
●1997年国防科技大学计算机应用专业并行算法方向博士毕业;
●1999年北京应用物理与计算数学数学博士后流动站出站,并留所工作;
●主要从事大规模科学与工程并行计算研究。
消息传递并行编程环境MPI
一、进程与消息传递
二、MPI环境的应用现状
三、MPI并行程序设计入门(程序例1)
四、初步的MPI消息传递函数
五、作业一
六、先进的MPI函数
七、MPI并行程序示例2(求解-u=f);
八、MPI环境的发展
九、作业二
一、进程与消息传递
1.单个进程(process)
●进程是一个程序,同时包含它的执行环境(内存、寄存器、程序计数器等),是操作系统中独立存在的可执行的基本程序单位;
●通俗理解:
串行应用程序编译形成的可执行代码,分为“指令”和“数据”两个部分,并在程序执行时“独立地申请和占有”内存空间,且所有计算均局限于该内存空间。
进程1
进程2
内存
2.单机内多个进程:
●多个进程可以同时存在于单机内同一操作系统:
由操作系统负责调度分时共享处理机资源(CPU、内存、存储、外设等);
●进程间相互独立(内存空间不相交):
在操作系统调度下各自独立地运行,例如多个串行应用程序在同一台计算机中运行;
●进程间可以相互交换信息:
例如数据交换、同步等待,消息是这些交换信息的基本单位,消息传递是指这些信息在进程间的相互交换,是实现进程间通信的唯一方式;
●最基本的消息传递操作:
发送消息(send)、接受消息(receive)、进程同步(barrier)、规约(reduction);
●消息传递的实现:
共享内存或信号量,用户不必关心;
进程1进程2
发送数据接收数据
(消息传递)
内存空间
3.包含于通过网络联接的不同计算机的多个进程:
●进程独立存在:
进程位于不同的计算机,由各自独立的操作系统调度,享有独立的CPU和内存资源;
●进程间相互信息交换:
消息传递;
●消息传递的实现:
基于网络socket机制,用户不必关心;
4.消息传递库函数:
●应用程序接口(API):
提供给应用程序(FORTRAN、C、C++语言)的可直接调用的完成进程间消息传递的某项特定功能的函数;
●消息传递库:
所有定义的消息传递函数编译形成的软件库,调用其内部函数的应用程序,通过与之联接,即可成为可并行执行的程序;
●目前流行的消息传递函数库:
PVM3.3.11、MPICH1.2、LAMMPI6.4等;
5.标准消息传递界面(MPI:
MessagePassingInterface):
●MPI标准:
根据应用程序对消息传递功能的需求,全球工业、应用和研究部门联合推出标准的消息传递界面函数,不考虑其具体实现,以保证并行应用程序的可移植性;
●MPI的具体实现:
消息传递库函数,目前有影响的为MPICH和LAMMPI,我们注重MPICH系列;
6.基于消息传递的并行程序执行模式:
●SPMD模式:
单程序多数据流
并行应用程序代码
可执行代码
运行
复制多份并独立执行,形成多个独立的进程
进程三(内存)
进程二(内存)
进程一(内存)
消息传递(交换数据、同步、规约)协同
●MPMD模式:
多程序多数据流,除初始启动多个可执行代码,其余与SPMD模式一致;
7.共享存储与分布式存储:
●属于并行机体系结构的范畴,与消息传递并行程序设计平台无关;
节点
CPU
CPU
CPU
CPU
CPU
CPU
M
M
M
互连网络
互连网络
M
M
M
分布式存储共享存储
●消息传递是相对于进程间通信方式而言的,与具体并行机存储模式无关,任何支持进程间通信的并行机,均可支持消息传递并行程序设计;
●几乎所有共享和分布存储并行计算环境均支持进程间的消息传递通信;
二、MPI环境的应用现状
●MPI(消息传递界面)是全球工业、政府和科研部门联合推出的适合进程间进行标准消息传递的并行程序设计平台,最初版MPI1.0本于1994年6月推出,目前最新的为MPI2.0版,于1998年年低推出;
●MPI的具体实现:
MPICH和LAMMPI,目前均已实现MPI1.2版,适用于任何并行计算平台;部分并行机已实现MPI2.0版;
●MPI是目前应用最广的并行程序设计平台,几乎被所有并行计算环境(共享和分布式存储并行机、MPP、机群系统等)和流行的多进程操作系统(UNIX、WindowsNT)所支持,基于它开发的应用程序具有最佳的可移植性;
●目前高效率的超大规模并行计算(1000个处理器)最可信赖的平台;
●工业、科学与工程计算部门的大量科研和工程软件(气象、石油、地震、空气动力学、核等)目前已经移植到MPI平台,发挥了重要作用;
●目前,MPI相对于PVM:
Ø优点:
功能强大,性能高,适应面广,使用方便,可扩展性好;
Ø缺点:
进程数不能动态改变;
三、MPI并行程序设计入门
1.MPI并行程序设计平台由标准消息传递函数及相关辅助函数构成,多个进程通过调用这些函数(类似调用子程序),进行通信;
2.MPI程序:
●SPMD执行模式:
一个程序同时启动多份,形成多个独立的进程,在不同的处理机上运行,拥有独立的内存空间,进程间通信通过调用MPI函数来实现;
●每个进程开始执行时,将获得一个唯一的序号(rank)。
例如启动P个进程,序号依次为0,1,…,P-1;
●MPI程序例1:
进程0发送一个整数给进程1;进程1将该数加1,传递给进程2;进程2再将该数加1,再传递给进程3;依次类推,最后,进程P-1将该数传递给进程0,由进程0负责广播该数给所有进程,并打印输出。
programexample1
include“mpif.h”!
!
MPI系统头文件
integerstatus(MPI_STATUS_SIZE),my_rank,p,source,dest,tag,ierr,data
c
c-------进入MPI系统
callMPI_Init(ierr)
callMPI_Comm_rank(MPI_COMM_WORLD,my_rank,ierr)
callMPI_Comm_size(MPI_COMM_WORLD,p,ierr)
c
c-------数据交换
data=0
tag=5
source=my_rank-1
if(source.eq.-1)source=p-1
dest=my_rank+1
if(dest.eq.p)dest=0
if(my_rank.eq.0)then
callMPI_Send(data,1,MPI_INTEGER,dest,tag,MPI_COMM_WORLD,ierr)
callMPI_Recv(data,1,MPI_INTEGER,source,tag,MPI_COMM_WORLD,status,ierr)
else
callMPI_Recv(data,1,MPI_INTEGER,source,tag,MPI_COMM_WORLD,status,ierr)
data=data+1
callMPI_Send(data,1,MPI_INTEGER,dest,tag,MPI_COMM_WORLD,ierr)
endif
c
c-------广播数据
callMPI_Bcast(data,1,MPI_INTEGER,0,MPI_COMM_WORLD,ierr)
c
c------打印输出
if(my_rank.eq.0)then
if(data.eq.p-1)then
print*,”Successful,data=”,data
else
print*,”Failure,data=”,data
endif
endif
c
callMPI_Finalize(ierr)
end
●
编译命令:
mpif77-oexam.eexample.f
●运行命令:
mpirun–np4exam.e
●运行效果:
MPI系统选择相同或不同的4个处理机,在每个处理机上运行程序代码exam.e。
MPI函数进程0进程1进程2进程3
进入MPI系统
Init()
Comm_rank()my_rank=0myrank=1myrank=2my_rank=3
Comm_size()p=4p=4p=4p=4
tag=5,data=0tag=5,data=0tag=5,data=0tag=5,data=0
source=3source=0source=1source=2
dest=1dest=2dest=3dest=0
数据交换send()recv()recv()recv()
recv()data=data+1
空send()
闲data=data+1
等send()
待data=data+1
消息传递send()
Broadcast()send()recv()recv()recv()
退出MPI系统
output“data”
Finalize()
3.MPI重要概念
●进程序号(rank);各进程通过函数MPI_Comm_rank()获取各自的序号;
●消息号:
消息的标号;
●通信器(Communicator):
1)理解为一类进程的集合,且在该集合内,进程间可以相互通信;类比:
邮局、电话局、国际网;2)任何MPI通信函数均必须在某个通信器内发生;3)MPI系统提供省缺的通信器MPI_COMM_WORLD,所有启动的MPI进程通过调用函数MPI_Init()包含在该通信器内;4)各进程通过函数MPI_Comm_size()获取通信器包含的(初始启动)的MPI进程个数;
●消息:
分为数据(data)和包装(envelope)两个部分,其中,包装由接收进程序号、发送进程序号、消息标号和通信器四部分组成,数据包含用户将要传递的内容;
●进程组:
一类进程的集合,在它的基础上,可以定义新的通信器;
●基本数据类型:
对应于FORTRAN和C语言的内部数据类型(INTEGER,REAL,DOUBLEPRECISION,COMPLEX,LOGICAL,CHARACTER),MPI系统提供已定义好的对应数据类型(MPI_INTEGER,MPI_REAL,MPI_DOUBLE_PRECISION,MPI_COMPLEX,MPI_LOGICAL,MPI_CHARACTER);
●自定义数据类型:
基于基本数据类型,用户自己定义的数据类型(后面介绍);
●MPI对象:
MPI系统内部定义的数据结构,包括数据类型、进程组、通信器等,它们对用户不透明,在FORTRAN语言中,所有MPI对象均必须说明为“整型变量INTEGER”;
●MPI联接器(handle):
联接MPI对象和用户的桥梁,用户可以通过它访问和参与相应MPI对象的具体操作;例如,MPI系统内部提供的通信器MPI_COMM_WORLD;在FORTRAN语言中,所有MPI联接器均必须说明为“整型变量INTEGER”;
●进程拓扑结构:
进程组内部进程之间的一种相互连接结构,如33网格,将在后面介绍。
33网格拓扑结构
●静态进程个数:
进程数由命令“mpirun–npxxx”初始确定为xxx个,程序执行过程中不能动态改变进程的个数;
●消息缓存区:
应用程序产生的消息包含的数据所处的内存空间;
●标准输入:
所有进程的标准输入read(*,*)均省缺为当前终端屏幕,且只能由0号进程执行该操作,其他进程需要这些输入参数,只能由0号进程执行数据广播操作;
●标准输出:
所有进程可以独立执行标准输出write(*,*),但其省缺为当前终端屏幕;
4.MPI函数格式:
●FORTAN语言中,最后一个参数为该函数调用是否成功的标志:
0表示成功,其它表示各种可能的错误;
●C语言中,该标志又函数参数返回;
C:
ierr=MPI_Comm_rank(myrank)
F:
MPI_Comm_rank(myrank,ierr)
5.MPI函数的使用查询:
●由函数名查询:
man函数名(MPI_Xxxx),注意大小写,例如manMPI_Comm_rank,manMPI_Send,manMPI_recv.
6.MPI函数的学习与使用:
●注重MPI函数的各类功能,由应用程序的通信需求出发,寻找匹配的函数类型,在查找具体函数名,采用man命令可以查询该函数的具体参数含义和使用方法。
●
7.一般的MPI程序设计流程图
程序参数说明
CallMPI_Init()
进入MPI系统,通信器
MPI_COMM_WORLD形成
CallMPI_Comm_rank()
CallMPI_Comm_size()
建立新的通信器、定义新的数据类型和进程拓扑结构
应用程序实体:
1.计算控制程序体;
2.进程间通信;
退出MPI系统
CallMPI_Finalize()
End
四、初步的MPI消息传递函数
1.点对点通信(point-to-point)
●定义:
给定属于同一通信器内的两个进程,其中一个发送消息,一个接收消息;
●MPI系统定义的所有通信方式均建立在点对点通信之上;
●四种模式:
标准模式、缓存区模式、同步模式、就绪模式;
2.标准模式点对点通信
●进程可以随意地发送(接收)消息,与是否存在匹配的消息接收(发送)进程无关;
进程0
进程1
发收匹配:
进程2
进程1
进程0
发收不匹配:
●两类:
⏹阻塞式:
消息发送函数返回,用户可以对消息缓存区进行处理,不会影响已发送的消息数据;接受函数返回,用户可以使用接受到的消息数据;
⏹非阻塞式:
发送和接受函数返回后,必须调用另一类函数来确保它们的正确完成;
阻塞式非阻塞式
INTEGERAINTEGERA
A=100A=100
MPI_Send(A,1,….)MPI_Isend(A,1,…)
A=200A=200
消息数据:
A=100A=100或A=200
MPI_Isend(A,1,…flag,…)
MPI_Wait(flag,…)
A=200
消息数据:
A=100A=100
3.点对点通信函数举例
●阻塞式标准消息发送函数
MPI_Send(buf,count,datatype,dest,tag,comm,ierr)
Real*8(integer,…)buf:
消息发送缓存区起始地址
(Fortran,用户的待发送的第一个数据)
integercount:
buf起始的数据单元个数
integerdatatype:
数据类型(基本或用户定义的)
integerdest:
接收进程序号
integertag:
消息的标号
integercomm:
通信器
integerierr:
函数调用返回错误码
real*8a(100,100)
integerb(60,60)
c-----发送50个双精度数“a(5,20):
a(54,20)”到2号进程
callMPI_Send(a(5,20),50,MPI_DOUBLE_PRECISION,2,
&99999,MPI_COMM_WORLD,ierr)
c-----发送20个整型数“b(20,40):
b(39,40)”到5号进程
callMPI_Send(b(20,40),20,MPI_DOUBLE_PRECISION,5,
&99999,MPI_COMM_WORLD,ierr)
●
阻塞式标准消息接收函数
MPI_Recv(buf,count,datatype,dest,tag,comm,status,ierr)
Real*8(integer,…)buf:
消息接收缓存区起始地址
(Fortran,用户用于接受的第一个数据)
integercount:
buf起始的数据单元个数
integerdatatype:
数据类型(基本或用户定义的)
integerdest:
发送进程序号
integertag:
消息的标号
integercomm:
通信器
integerstatus(MPI_STATUS_SIZE):
接收状态数组;
integerierr:
函数调用返回错误码
real*8a(100,100)
integerb(60,60)
c-----从2号进程接收50个双精度数到“a(5,20):
a(54,20)”
callMPI_Recv(a(5,20),50,MPI_DOUBLE_PRECISION,2,
&99999,MPI_COMM_WORLD,status,ierr)
c-----从5号进程接收20个整型数到“b(20,40):
b(39,40)”
callMPI_Recv(b(20,40),20,MPI_DOUBLE_PRECISION,5,
&99999,MPI_COMM_WORLD,status,ierr)
●其他点对点通信函数:
参考手册;
4.聚合通信(CollectiveCommunication)
●定义:
属于同一通信器的所有MPI进程均必须参与的通信操作;
●参与方式:
调用同一聚合通信函数;
●函数类型:
Ø同步通信函数:
所有进程在某个程序点上同步;
MPI_Barrier(comm,ierr)
Ø全局通信函数:
✦广播:
MPI_Bcast(buf,count,dtype,root,comm,ierr)
root发送
other接受
✦收集:
MPI_Gather(bufs,bufr,count,dtype,root,comm,ierr)
all发送大小一致的数据块
root接受并按序号连续存放
✦全收集:
MPI_Allgather()
all发送
all接受
✦索引收集:
MPI_Gatherv()
all发送大小不等的数据块
root接受并按索引间断存放
✦索引全收集:
MPI_Allgatherv()
all发送大小不等的数据块
All接受并按索引间断存放
✦
✦分散:
MPI_Scatter(bufs,bufr,count,dtype,root,comm,ierr)
root发送连续的大小一致数据块
All接受
✦索引分散:
MPI_Scatterv()
root发送间断的大小不一致数据块
All接受
✦全交换:
MPI_Alltoall()
All发送大小一致数据块到各进程
All接受大小一致数据块并按序号连续存放
✦索引全交换:
MPI_Alltoallv()
Ø全局规约(globalreduction)函数:
✦规约:
MPI_Reduce(sbuf,rbuf,count,dtype,op,root,comm,ierr);
规约操作类型op:
MPI_SUM,MPI_MIN,MPI_MAX,MPI_PROD等12种;
例子:
求两个向量的内积,并将结果返回进程0
subroutinepar_blas1(m,a,b,c,comm)
reala(m),b(m)!
localsliceofarray
realc!
result
realsum
integerm,comm,i,ierr
c
c!
localsum
sum=0.0d0
doi=1,m
sum=sum+a(i)*b(i)
enddo
c!
globalsum
callMPI_Reduce(sum,c,1,MPI_REAL,MPI_SUM,0,
&comm,ierr)
✦全规约:
MPI_Allreduce(),除要求将结果返回到所有进程外,与MPI_Reduce()一致;
✦规约分散:
MPI_Reduce_scatter(),将规约结果分散到各进程;
✦并行前缀计算:
MPI_Scan()
五、作业一
P个进程,第i个进程将其包含100个双精度数据的数组A(100)传送给第(i+1)modP个进程,同时从第(i-1)modP个进程接受100个双精度数据到另一个数组B(100)中,令数组C(1:
100)=A(1:
100)+B(1:
100),然后求数组C(1:
100)各元素的类加和,最后在将该和全部累加到0号进程,打印并输出该和。
提示:
可在例1的基础上修改,编制。
六、先进的MPI函数
1.自定义数据类型
●定义:
在MPI系统已定义的基本数据类型(MPI_INTEGER,MPI_REAL,MPI_DOUBLE_PRECISION,MPI_CHARACTER等)基础上,用户根据需求,自己定义的数据类型;
reala(1000)
发送:
a(5:
9)
callMPI_Send(a(5),5,MPI_REAL,…..)OK
发送:
a(5),a(7),a(9),a(11),a(13),a(15)
doi=5,15,2
callMPI_Send(a(i),1,MPI_REAL,….)OK
enddo
缺点:
多次发送,效率低,程序设计繁琐
改进:
用户定义新的数据类型
callMPI_Type_vector(5,1,2,MPI_REAL,newtype,ierr)
callMPI_Type_commit(newtype,ierr)提交
callMPI_Send(a(5),1,newtype,….)
callMPI_Type_free(newtype,ierr)释放
●在用户已定义好的数据类型基础上,还可以进一步定义新的数据类型;
●用户定义的数据类型,必须由函数MPI_Type_Commit()提交给MPI系统;此后,就可以象基本数据类型一样,在消息传递函数中重复使用;并由函数MPI_Type_free()释放;
●具体
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 消息 传递 并行 编程 环境 MPI
![提示](https://static.bdocx.com/images/bang_tan.gif)