基于MPI的并行程序设计 王振海 西北工业大学理学院 西北工业大学高性能计算研究与发展中心 2018/11/28
主要内容 MPI并行编程环境 进程与消息传递 MPI并行程序设计入门 初步的MPI消息传递函数 先进的MPI函数 MPI并行程序示例 进程与消息传递 MPI并行程序设计入门 初步的MPI消息传递函数 先进的MPI函数 MPI并行程序示例 面向性能的程序设计 2018/11/28
并行编程环境简介 目前,高性能并行机主要可以分为对称多处理共享存储并行机(SMP, Symmetric MultiProcessor)、分布式共享存储多处理机 (DSM, Distributied Shared Memory)、大规模并行处理机(MPP, Massively Parallel Processor)和微机机群(Cluster)等四类。在这些并行机上,并行程序设计平台主要可分为消息传递、共享存储和数据并行三类,其中消息传递具有很好的可移植性,它能被所有这些类型的并行机所支持,而共享存储只能在在SMP和DSM并行机中使用,数据并行只能在SMP,DSM和MPP并行机上使用。 2018/11/28
MPI并行编程环境 消息传递并行编程环境(MPI:Message Passing Interface) 是目前国际上最流行、可移植性和可扩展性很好的并行程序设计平台,并被当前流行的所有高性能并行机所支持。它是在标准串行程序设计语言(C,Fortran,C++)的基础上,再加入实现进程间通信的MPI消息传递库函数,就构成了MPI并行程序设计所依赖的并行编程环境。 MPI已经在Windows系列的非Unix、Linux平台上实现,其程序设计语言支持C, Fortran和Java。在国产的三大并行机系列神威、银河和曙光上也都实现了对MPI和支持。 2018/11/28
MPI并行环境的应用现状 MPI是全球工业、政府和科研部门联合推出的适合进程间进行标准消息传递的并行程序设计平台,最初版MPI 1.0本于1994年6月推出,目前最新的为MPI 2.0版,于1998年10月推出。 MPI的具体实现:MPICH和LAMMPI,目前均已实现MPI 1.2版,适用于任何并行计算平台;部分并行机已实现MPI 2.0版。 MPI是目前应用最广的并行程序设计平台,几乎被所有并行计算环境(共享和分布式存储并行机、MPP、机群系统等)和流行的多进程操作系统(UNIX、Windows NT)所支持,基于它开发的应用程序具有最佳的可移植性。 2018/11/28
目前高效率的超大规模并行计算(1000个处理器)最可信赖的平台。 MPI并行环境的应用现状(续) 目前高效率的超大规模并行计算(1000个处理器)最可信赖的平台。 工业、科学与工程计算部门的大量科研和工程软件(气象、石油、地震、空气动力学、核等)目前已经移植到MPI平台,发挥了重要作用。 MPI的优点:(1)具有很好的可移植性,几乎被所有的并行环境支持;(2)具有很好的可扩展性,是目前高效率的大规模并行计算最可信赖的平台;(3)比其它消息传递系统好用;(4)有完备的异步通信功能;(5)有精确的定义,从而为并行软件产业的发展提供了必要的条件。 2018/11/28
目前,各类并行机,特别式微机机群,只实现了MPI 2.0的部分功能。本中心机群所支持的为MPI 1.2.5版本。 MPI 2.0版在1.0版的基础上,增加了如下的消息传递功能:(1)并行I/O:允许多个进程同时读写同一个文件;(2)线程安全:允许MPI进程的多个线程执行,即支持与OpenMP的混合并行编程;(3)动态进程管理:允许并行应用程序在执行过程中,动态地增加和删除进程个数;(4)单边通信:允许某个进程对其它进程的局部内存单元直接执行读写访问,而步需要对方进程的显式干预;(5)并行应用程序之间的动态互操作:允许各个MPI并行应用程序之间动态地建立和删除消息传递通道。 目前,各类并行机,特别式微机机群,只实现了MPI 2.0的部分功能。本中心机群所支持的为MPI 1.2.5版本。 2018/11/28
MPI并行编程环境 进程与消息传递 MPI并行程序设计入门 初步的MPI消息传递函数 先进的MPI函数 MPI并行程序示例 进程与消息传递 MPI并行程序设计入门 初步的MPI消息传递函数 先进的MPI函数 MPI并行程序示例 面向性能的程序设计 2018/11/28
单个进程(process) 进程是一个程序,同时包含它的执行环境(内存、寄存器、程序计数器等),是操作系统中独立存在的可执行的基本程序单位。 通俗理解:串行应用程序编译形成的可执行代码,分为“指令”和“数据”两个部分,并在程序执行时“独立地申请和占有”内存空间,且所有计算均局限于该内存空间。 进程1 内存 进程2 2018/11/28
单机内多个进程 多个进程可以同时存在于单机内同一操作系统:由操作系统负责调度分时共享处理机资源(CPU、内存、存储、外设等)。 进程间相互独立(内存空间不相交):在操作系统调度下各自独立地运行,例如多个串行应用程序在同一台计算机中运行。 进程间可以相互交换信息:例如数据交换、同步等待,消息是这些交换信息的基本单位,消息传递是指这些信息在进程间的相互交换,是实现进程间通信的唯一方式。 2018/11/28
最基本的消息传递操作:发送消息(send)、接受消息(receive)、进程同步(barrier)、规约(reduction)。 单机内多个进程(续) 最基本的消息传递操作:发送消息(send)、接受消息(receive)、进程同步(barrier)、规约(reduction)。 消息传递的实现:共享内存或信号量,用户不必关心。 2018/11/28
包含于通过网络联接的不同计算机的多个进程 进程独立存在:进程位于不同的计算机,由各自独立的操作系统调度,享有独立的CPU和内存资源。 进程间相互信息交换:消息传递。 消息传递的实现:基于网络socket机制,用户不必关心。 2018/11/28
消息传递库函数 应用程序接口(API):提供给应用程序(FORTRAN、C、C++语言)的可直接调用的完成进程间消息传递的某项特定功能的函数。 消息传递库:所有定义的消息传递函数编译形成的软件库,调用其内部函数的应用程序,通过与之联接,即可成为可并行执行的程序。 目前流行的消息传递函数库:PVM 3.3.11、MPICH 1.2、LAMMPI 6.4等。 2018/11/28
标准消息传递界面MPI MPI标准:根据应用程序对消息传递功能的需求,全球工业、应用和研究部门联合推出标准的消息传递界面函数,不考虑其具体实现,以保证并行应用程序的可移植性 。 MPI的具体实现:消息传递库函数,目前有影响的为MPICH和LAMMPI,我们注重MPICH系列。 2018/11/28
基于消息传递的并行程序执行模式 SPMD模式:单程序多数据流 2018/11/28
MPM模式:多程序多数据流,除初始启动多个可执行代码,其余与SPMD模式一致。 基于消息传递的并行程序执行模式(续) MPM模式:多程序多数据流,除初始启动多个可执行代码,其余与SPMD模式一致。 2018/11/28
共享存储与分布式存储 属于并行机体系结构的范畴,与消息传递并行程序设计平台无关。 2018/11/28
消息传递是相对于进程间通信方式而言的,与具体并行机存储模式无关,任何支持进程间通信的并行机,均可支持消息传递并行程序设计。 共享存储与分布式存储(续) 消息传递是相对于进程间通信方式而言的,与具体并行机存储模式无关,任何支持进程间通信的并行机,均可支持消息传递并行程序设计。 几乎所有共享和分布存储并行计算环境均支持进程间的消息传递通信。 2018/11/28
MPI并行编程环境 进程与消息传递 MPI并行程序设计入门 初步的MPI消息传递函数 先进的MPI函数 MPI并行程序示例 进程与消息传递 MPI并行程序设计入门 初步的MPI消息传递函数 先进的MPI函数 MPI并行程序示例 面向性能的程序设计 2018/11/28
MPI并行程序 MPI并行程序设计平台由标准消息传递函数及相关辅助函数构成,多个进程通过调用这些函数(类似调用子程序),进行通信。 SPMD执行模式:一个程序同时启动多份,形成多个独立的进程,在不同的处理机上运行,拥有独立的内存空间,进程间通信通过调用MPI函数来实现。 每个进程开始执行时,将获得一个唯一的序号(rank)。例如启动P个进程,序号依次为0,1,…,P-1。 2018/11/28
MPI并行程序例1 进程0发送一个整数给进程1;进程1将该数加1,传递给进程2;进程2再将该数加1,再传递给进程3;依次类推,最后,进程P-1将该数传递给进程0,由进程0负责广播该数给所有进程,并打印输出。 program example1 include “mpif.h” !! MPI系统头文件 integer status(MPI_STATUS_SIZE), my_rank,p integer source,dest,tag,ierr,data c 2018/11/28
MPI并行程序例1(续) c-------进入MPI系统 call MPI_Init(ierr) call MPI_Comm_rank(MPI_COMM_WORLD,my_rank,ierr) call MPI_Comm_size(MPI_COMM_WORLD,p,ierr) 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 2018/11/28
MPI并行程序例1(续) if(my_rank.eq.0) then call MPI_Send(data,1,MPI_INTEGER,dest,tag,MPI_COMM_WORLD,ierr) call MPI_Recv(data,1,MPI_INTEGER,source,tag,MPI_COMM_WORLD,status,ierr) else data=data+1 endif c 2018/11/28
MPI并行程序例1(续) c-------广播数据 call MPI_Bcast(data,1,MPI_INTEGER,0,MPI_COMM_WORLD,ierr) c------打印输出 if(my_rank.eq.0) then if(data.eq.p-1) then print *,”Successful, data=”,data else print *,”Failure, data=”,data endif c call MPI_Finalize(ierr) end 2018/11/28
MPI并行程序的运行 MPI编译命令: mpif77 -o exam.e example.f 运行命令: mpirun –np 4 exam.e 运行效果:MPI系统选择相同或不同的4个处理机,在每个处理机上运行程序代码exam.e。 运行结果: Successful, data=3 2018/11/28
运行分析 2018/11/28
MPI重要概念 进程序号(rank):各进程通过函数MPI_Comm_rank()获取各自的序号。 消息号:消息的标号。 通信器(Communicator) :1)理解为一类进程的集合,且在该集合内,进程间可以相互通信;类比:邮局、电话局、国际网;2)任何MPI通信函数均必须在某个通信器内发生;3) MPI系统提供省缺的通信器MPI_COMM_WORLD,所有启动的MPI进程通过调用函数MPI_Init()包含在该通信器内;4)各进程通过函数MPI_Comm_size()获取通信器包含的(初始启动)的MPI进程个数。 2018/11/28
进程组:一类进程的集合,在它的基础上,可以定义新的通信器。 MPI重要概念(续) 消息:分为数据(data)和包装(envelope)两个部分,其中,包装由接收进程序号、发送进程序号、消息标号和通信器四部分组成,数据包含用户将要传递的内容。 进程组:一类进程的集合,在它的基础上,可以定义新的通信器。 基本数据类型:对应于FORTRAN和C语言的内部数据类型(INTEGER,REAL,DOUBLE PRECISION,COMPLEX,LOGICAL,CHARACTER),MPI系统提供已定义好的对应数据类型(MPI_INTEGER,MPI_REAL,MPI_DOUBLE_PRECISION,MPI_COMPLEX,MPI_LOGICAL,MPI_CHARACTER)。 2018/11/28
自定义数据类型:基于基本数据类型,用户自己定义的数据类型(后面介绍)。 MPI重要概念(续) 自定义数据类型:基于基本数据类型,用户自己定义的数据类型(后面介绍)。 MPI对象:MPI系统内部定义的数据结构,包括数据类型、进程组、通信器等,它们对用户不透明,在FORTRAN语言中,所有MPI对象均必须说明为“整型变量INTEGER”。 MPI联接器(handle):联接MPI对象和用户的桥梁,用户可以通过它访问和参与相应MPI对象的具体操作;例如,MPI系统内部提供的通信器MPI_COMM_WORLD;在FORTRAN语言中,所有MPI联接器均必须说明为“整型变量INTEGER” 。 2018/11/28
进程拓扑结构:进程组内部进程之间的一种相互连接结构,如33 网格,将在后面介绍。 MPI重要概念(续) 进程拓扑结构:进程组内部进程之间的一种相互连接结构,如33 网格,将在后面介绍。 3×3 网格拓扑结构 静态进程个数:进程数由命令“mpirun –np xxx”初始确定为xxx个,程序执行过程中不能动态改变进程的个数 。 2018/11/28
消息缓存区:应用程序产生的消息包含的数据所处的内存空间。 MPI重要概念(续) 消息缓存区:应用程序产生的消息包含的数据所处的内存空间。 标准输入:所有进程的标准输入read(*,*)均省缺为当前终端屏幕,且只能由0号进程执行该操作,其他进程需要这些输入参数,只能由0号进程执行数据广播操作。 标准输出:所有进程可以独立执行标准输出write(*,*),但其省缺为当前终端屏幕。 2018/11/28
MPI函数格式 FORTAN语言中,最后一个参数为该函数调用是否成功的标志:0表示成功,其它表示各种可能的错误。 C语言中,该标志有函数参数返回。 C : ierr=MPI_Comm_rank(myrank) F : MPI_Comm_rank(myrank,ierr) 2018/11/28
MPI函数的使用查询 由函数名查询: man 函数名 ( MPI_Xxxx), 注意大小写,例如 man MPI_Comm_rank man MPI_Send man MPI_recv 2018/11/28
MPI函数的学习与使用 注重MPI函数的各类功能,由应用程序的通信需求出发,寻找匹配的函数类型,在查找具体函数名,采用man命令可以查询该函数的具体参数含义和使用方法。 2018/11/28
建立新的通信器、定义新的数据类型和进程拓扑结构 一般的MPI程序设计流程图 程序参数说明 进入MPI系统,通信器 MPI_COMM_WORLD形成 Call MPI_Init ( ) Call MPI_Comm_rank ( ) Call MPI_Comm_size ( ) 建立新的通信器、定义新的数据类型和进程拓扑结构 2018/11/28
一般的MPI程序设计流程图(续) 应用程序实体: .计算控制程序体; .进程间通信; 退出MPI系统 Call MPI_Finalize ( ) End 2018/11/28
MPI并行编程环境 进程与消息传递 MPI并行程序设计入门 初步的MPI消息传递函数 先进的MPI函数 MPI并行程序示例 进程与消息传递 MPI并行程序设计入门 初步的MPI消息传递函数 先进的MPI函数 MPI并行程序示例 面向性能的程序设计 2018/11/28
点对点通信(point-to-point) 定义:给定属于同一通信器内的两个进程,其中一个发送消息,一个接收消息。 MPI系统定义的所有通信方式均建立在点对点通信之上。 四种模式:标准模式、缓存区模式、同步模式、就绪模式。 2018/11/28
标准模式点对点通信 进程可以随意地发送(接收)消息,与是否存在匹配的消息接收(发送)进程无关。 发收匹配: 进程0 进程1 发收不匹配: 进程2 2018/11/28
阻塞式:消息发送函数返回,用户可以对消息缓存区进行处理,不会影响已发送的消息数据;接收函数返回,用户可以使用接收到的消息数据。 标准模式点对点通信的分类 阻塞式:消息发送函数返回,用户可以对消息缓存区进行处理,不会影响已发送的消息数据;接收函数返回,用户可以使用接收到的消息数据。 非阻塞式:发送和接受函数返回后,必须调用另一类函数来确保它们的正确完成。 2018/11/28
标准模式点对点通信的分类举例 2018/11/28
点对点通信函数举例 阻塞式标准消息发送函数 MPI_Send(buf,count,datatype,dest,tag,comm,ierr) Real*8(integer,…)buf : 消息发送缓存区起始地址 (Fortran, 用户的待发送的第一个数据) integer count :buf起始的数据单元个数 integer datatype :数据类型(基本或用户定义的) integer dest : 接收进程序号 integer tag : 消息的标号 integer comm : 通信器 integer ierr : 函数调用返回错误码 2018/11/28
阻塞式标准消息发送函数举例 real *8 a(100,100) integer b(60,60) c-----发送50个双精度数“a(5,20) : a(54,20)”到2号进程 call MPI_Send( a (5,20),50,MPI_DOUBLE_PRECISION,2, & 99999,MPI_COMM_WORLD,ierr ) c-----发送20个整型数“b(20,40) : b(39,40)”到5号进程 call MPI_Send( b (20,40),20,MPI_DOUBLE_PRECISION,5, 2018/11/28
阻塞式标准消息接收函数 MPI_Recv(buf,count,datatype,dest,tag,comm,status, ierr) Real*8(integer,…)buf : 消息接收缓存区起始地址 (Fortran, 用户用于接受的第一个数据) integer count :buf起始的数据单元个数 integer datatype :数据类型(基本或用户定义的) integer dest : 发送进程序号 integer tag : 消息的标号 integer comm : 通信器 integer status(MPI_STATUS_SIZE) : 接收状态数组; integer ierr : 函数调用返回错误码 2018/11/28
阻塞式标准消息接收函数举例 其他点对点通信函数:参考手册。 real *8 a(100,100) integer b(60,60) c-----从2号进程接收50个双精度数到“a(5,20) : a(54,20)” call MPI_Recv( a (5,20),50,MPI_DOUBLE_PRECISION,2, & 99999,MPI_COMM_WORLD,status,ierr ) c-----从5号进程接收20个整型数到“b(20,40) : b(39,40)” call MPI_Recv( b (20,40),20,MPI_DOUBLE_PRECISION,5, 其他点对点通信函数:参考手册。 2018/11/28
聚合通信(Collective Communication) 定义:属于同一通信器的所有MPI进程均必须参与的通信操作。 参与方式:调用同一聚合通信函数。 函数类型: 同步通信函数:所有进程在某个程序点上同步。 MPI_Barrier ( comm , ierr ) 全局通信函数 全局规约函数 2018/11/28
广播: MPI_Bcast(buf,count,dtype,root,comm,ierr) root 发送 other 接收 全局通信函数 广播: 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 接收 2018/11/28
索引全收集:MPI_Allgatherv() all 发送大小不等的数据块 all 接收并按索引间断存放 全局通信函数(续) 索引收集:MPI_Gatherv() all 发送大小不等的数据块 root 接收并按索引间断存放 索引全收集:MPI_Allgatherv() all 发送大小不等的数据块 all 接收并按索引间断存放 2018/11/28
分散:MPI_Scatter(bufs,bufr,count,dtype,root,comm,ierr) 全局通信函数(续) 分散:MPI_Scatter(bufs,bufr,count,dtype,root,comm,ierr) root 发送连续的大小一致的数据块 all 接收 索引分散:MPI_Scatterv() root 发送间断的的大小不一致的数据块 全交换:MPI_Scatterv() all 发送大小一致数据块到各进程 all 接收大小一致数据块并按序号连续存放 2018/11/28
全局规约(global reduction)函数 规约:MPI_Reduce(sbuf,rbuf,count,dtype,op,root, comm,ierr) 规约操作类型op : MPI_SUM, MPI_MIN, MPI_MAX, MPI_PROD等12种。 全规约:MPI_Allreduce() 除要求将结果返回到所有进程外,与MPI_Reduce()一致 规约分散:MPI_Reduce_scatter() 将规约结果分散到各进程。 并行前缀计算:MPI_Scan() 2018/11/28
MPI并行编程环境 进程与消息传递 MPI并行程序设计入门 初步的MPI消息传递函数 先进的MPI函数 MPI并行程序示例 进程与消息传递 MPI并行程序设计入门 初步的MPI消息传递函数 先进的MPI函数 MPI并行程序示例 面向性能的程序设计 2018/11/28
自定义数据类型 定义:在MPI系统已定义的基本数据类型(MPI_INTEGER,MPI_REAL,MPI_DOUBLE_PRECISION,MPI_CHARACTER等)基础上,用户根据需求,自己定义的数据类型。 在用户已定义好的数据类型基础上,还可以进一步定义新的数据类型。 用户定义的数据类型,必须由函数MPI_Type_Commit()提交给MPI系统;此后,就可以象基本数据类型一样,在消息传递函数中重复使用;并由函数MPI_Type_free()释放。 具体自定义数据类型函数,请参考手册。 2018/11/28
call MPI_Send(a(5), 5, MPI_ REAL,…..) OK 自定义数据类型(续) real a(1000) 发送: a(5:9) call MPI_Send(a(5), 5, MPI_ REAL,…..) OK 发送: a(5),a(7),a(9),a(11),a(13),a(15) do i=5, 15, 2 call MPI_Send(a(i),1,MPI_REAL,….) OK enddo 缺点: 多次发送,效率低,程序设计繁琐 改进:用户定义新的数据类型 call MPI_Type_vector(5,1,2,MPI_REAL,newtype,ierr) call MPI_Type_commit(newtype , ierr) 提交 call MPI_Send(a(5), 1, newtype,….) call MPI_Type_free(newtype,ierr) 释放 2018/11/28
进程拓扑结构 定义:根据应用程序的特征,在进程间建立的一种虚拟拓扑连接方式,以方便并行程序设计和提高并行计算性能。 例:二维规则区域,3*3 区域分解,9个进程,建立Cartesion坐标,进程(i,j)的相邻进程为(i-1,j), (i+1,j), (i,j-1), (i,j+1)。 2018/11/28
并行I/O 各进程可以类似于串行程序独立地读/写不同的文件。 MPICH 1.2以上版本支持所有进程并行读写同一个文件。 2018/11/28
MPI并行编程环境 进程与消息传递 MPI并行程序设计入门 初步的MPI消息传递函数 先进的MPI函数 MPI并行程序示例 进程与消息传递 MPI并行程序设计入门 初步的MPI消息传递函数 先进的MPI函数 MPI并行程序示例 面向性能的程序设计 2018/11/28
MPI并行程序例2 矩阵乘积:A为M×N阶矩阵,B为N×L阶矩阵,C为M×L阶矩阵。计算矩阵乘积C=AB。 算法描述:假设使用nprocs个MPI进程,为简单起见假定M和L均为nprocs的倍数。A和C按行等分成子块分别存储在不同的进程中,而B则按列等分成子块分别存储在不同的进程中。A,B和C的子块大小分别为mloc×N,N×lloc和mloc×L,其中mloc=M/nprocs,lloc=L/nprocs。具体存储方式为(k=0,…,nprocs-1): 存储在进程k的数组A中 存储在进程k的数组B中 存储在进程k的数组C中 2018/11/28
算法:矩阵A和C的子块不动,矩阵B的子块在各个进程间循环移动。如图,是当nprocs=3时的计算流程示意图。 MPI并行程序例2(续) 算法:矩阵A和C的子块不动,矩阵B的子块在各个进程间循环移动。如图,是当nprocs=3时的计算流程示意图。 A0 A1 A2 × B0 B1 B2 = A0×B0 A0×B1 A0×B2 C0 A1×B0 A1×B1 A1×B2 C1 A2×B0 A2×B1 A2×B2 C2 A0 B0 B2 B1 A1 A2 进程1 进程2 进程3 2018/11/28
乘法子程序使用MPI_Sendrecv_replace。(ex1.f) MPI并行程序:主程序负责分配存储单元并生成矩阵A和B的子块,然后调用子程序matmul完成矩阵的乘法运算。其中nprocs为MPI进程数,myrank为当前进程的MPI进程号。数组A,B和C分别存储矩阵A,B和C的子块。work为工作数组,大小与数组B一样。 乘法子程序使用MPI_Sendrecv_replace。(ex1.f) 使用异步通信函数MPI_Isend/MPI_Irecv,在适当的硬件环境下它可以使得计算与通信重叠进行。(ex2.f) 调用BLAS库函数完成矩阵子块的乘积。选用适当的BLAS库可以大幅度提高程序的实际运行性能。注意,编译该程序时必须与BLAS库连接。(ex3.f) 2018/11/28
MPI并行程序例3 一维Dirichlet问题: 算法:均匀网格有限差分离散,Jacobi迭代求解。 区域分解:nproc=4, n = 21, ns = (n-1)/nproc+1 =6 源程序:1dpoisson.f 2018/11/28
MPI并行编程环境 进程与消息传递 MPI并行程序设计入门 初步的MPI消息传递函数 先进的MPI函数 MPI并行程序示例 进程与消息传递 MPI并行程序设计入门 初步的MPI消息传递函数 先进的MPI函数 MPI并行程序示例 面向性能的程序设计 2018/11/28
设计高性能并行程序的要点与技术 划分阶段的性能问题 在多存储系统中的数据访问和通信 性能的整合 从处理器角度看到的性能因素 程序设计模型的影响 2018/11/28
划分阶段的性能问题 在分解和分配步骤中,我们可以将并行计算机系统简单地看作是一个相互合作的处理器集合,不用考虑程序设计模型和硬件系统组织。我们只需知道在处理器之间的通信开销是很大的。此时,在算法方面的三个基本要素是: 平衡负载,减少花在等待同步事件上的时间 减少通信开销 减少由确定和管理分配所带来的附加工作 不幸的是,即使这三种基本目标也是相互冲突的,必须进行折衷权衡。 2018/11/28
平衡负载和减少同步等待时间的过程分为四步 在分解中识别足够的并发性(数据并行和功能并行); 决定管理并发性的方式(静态分配和动态分配的对比); 确定并发性开发的粒度; 降低序列化和同步代价。 2018/11/28
在多存储系统中的数据访问和通信 多处理器系统也是多存储器系统,多缓存系统。系统这些组成部分的作用对程序执行性能是十分重要的,并且其重要性与程序设计模型无关(尽管程序设计模型可能影响某些性能折衷考虑的特性)。在这里,我们从一种不同的角度来看多处理器系统。 多处理器系统看成为扩展的存储层次结构 在扩展的存储层次中的附加通信 用工作集的观念看人为的通信和数据的复制 2018/11/28
性能的整合 减少人为通信:开发时间局部性与空间局部性; 将通信结构化以降低开销:通过减少通信开销和降低延迟,增加带宽,减少占有度,提供机制来分散冲突,用计算和通信来重叠通信 。 2018/11/28
从处理器角度看到的性能因素 在我们通常的分布存储并行系统结构上,并行执行时间有五个分量: 忙有用:处理器花在执行指令上的时间,那些指令本来在串行程序中也是要执行的。假设一个直接从串行算法中导出的确定性的并行程序,所有处理器的有用忙时间之和等于串行执行的有用忙时间。 忙开销:处理器花在执行那些在串行程序中不需要的指令上的时间。这直接对应于并行程序中的额外工作部分。 数据局部:等待数据引用被它自己的存储系统满足的时间;即等待的引用不会产生和其它节点的通信。 数据远程:等待数据通信的时间,无论是固有通信还是附加通信。这代表处理器看到的通信代价。 2018/11/28
从处理器角度看到的性能因素(续) 同步:等待其它进程给出某个事件发生的信号,有了该信号,本进程才能推进。这包括负载不平衡和程序中的串行化现象,还有实际花在执行同步操作和访问同步变量上的时间。当它等待的时候,一个处理器可能重复检测某个变量的值,直到改变—这就要执行指令—或者它停滞等待,这取决于同步的实现方式。 同步、忙开销、远程数据访问分量是由于并行所引入的开销,在串行程序在单处理器上执行没有。固有通信大多数包含在远程数据分量中,它的某些(通常很小)部分可能也在数据局部分量中体现出来。 2018/11/28
程序设计模型的影响 经验表明,随着应用变得更复杂和更非规则,透明命名和复制的有用性增加,这是倾向于共享存储的观点。然而,由于通信自然是细粒度的(特别是非规则应用),还由于大粒度通信和一致性引起的性能问题,支持共享空间就要求有大胆的通信系统结构,用硬件来支持大多数功能。许多计算机公司现在正建造这样的机器,作为它们的高端系统。在另一方面,便宜的工作站或者多处理器群也正在逐步流行起来。这些系统通常是消息传递程序设计的,这是由于消息传递的性能模型比较好定义,可以用大消息来分摊开销,程序员有显式的控制,以及不同的机器操作粒度对性能的相对影响不大。 2018/11/28
总结评述 我们已经看到,性能的方方面面是相互制约的,设计好的并行程序的艺术在于在相互矛盾的要求中获得适当的折衷。以高性能为目标的程序设计也是一个逐步求精的过程:在后面所发现的系统或者程序的特点,可能导致在前一个步骤中作的决定被修改。将性能的潜力都发挥出来可能需要很大的努力,这取决于应用和系统两个方面。进而,不同技术一起发挥作用的程度和方式能够大大影响表现给系统结构的负载的特点。 2018/11/28
问题讨论 请联系 王振海、赵俊峰 Tel:88493550-17 Email:zhwang@nwpu.edu.cn zhaojf_77@hotmail.com 2018/11/28
Thanks! 2018/11/28