并行程序设计.ppt
《并行程序设计.ppt》由会员分享,可在线阅读,更多相关《并行程序设计.ppt(108页珍藏版)》请在课桌文档上搜索。
1、2 并行程序设计,2.1 三种并行程序设计模型,1.数据并行模型(适用于SIMD并行机)代表编程工具:Fortran 90,HPF2.共享存储模型(适于共享存储多处理器)代表编程工具:Pthread,OpenMP3.消息传递模型(适于多计算机)代表编程工具:MPI,PVM,1 数据并行模型(Data Parallel),概况:数据并行即将相同的操作同时作用于不同的数据,数据并行编程模型提供给编程者一个全局的地址空间.特点:单线程;并行操作于密集的数据结构松散同步;全局命名空间隐式相互作用;隐式/半隐式数据分布,编程工具代表:Fortran90是一种流行的数据并行语言,对Fortran做修改,增
2、加了并行性支持。支持元素的并行数据操作,将整个数组成数组的一部分,视为一个操作数。高性能FORTRAN(HPF),HPF是一个语言标准,作为Fortran90的扩展。,一个简单的HPF程序实例,PROGRAM EXAMPLE!DECLARE VARIABLE INTEGER a(1024),b(1024),c(1024)INTEGER:result=0!DECLARE DISTRIBUTE!HPF$DISTRIBUTE a(block)!HPF$DISTRIBUTE b(block)!HPF$DISTRIBUTE c(block)!ALIGN VALUES TO DISTRIBUTED VAR
3、IABLES a=1 b=2!ADD THEM c=a+b!CALCULATE THE SUM IN ALL ELEMENTS OF c result=SUM(c)!PRINT THE RESULT PRINT*,“The last element is”,c(1024)PRINT*,“The sum in all elements is”,resultEND,分布数组的赋值,分布数组间的运算,分布数组的归约,打印分布数组元素,The last element is 3The sum in all elements is 3072,The last element is 3The sum in
4、 all elements is 3072,第一步:程序声明了三个整型数组,大小为1024。第二步:通过数据分布指令DISTRIBUTE指示将数组a按块分布方式block分配到各处理器上。上图给出的就是3个分布数组在4个处理器上的分布。第三步:是分布数组的赋值。采用属主规则(每个处理器尽量只访问分配给自己的数据段)。第四步:多个分布数组之间进行运算。(a和b中相应元素相加后送给c的相应元素)。第五步:分布数组的归约是将c数组中所有元素求和,赋给顺序变量result。(根据属主规则,各处理器并行地将属于自己的元素局部求和,然后调用全局操作归约并返回,将各处理器的局部和相加,再广播给所有处理器的r
5、esult变量。)最后一步:打印分布数组元素。HPF中I/O语句在非并行代码段中,在处理器0上执行。由于分布数组可以看成是分布共享的,因此具有共享属性,处理器可以访问任意一个分布数组的元素。例程中:处理器0访问了处理器3上的分布数组元素,引起了处理期间通信。,2 共享存储器模型,共享存储器编程的主要特征是共享存储器提供了创建出能够直接被所有的处理器访问而不用消息传递环境中那样用消息来传递数据的变量和数据结构。描述并发进程结构的最早例子是FORK-JOIN结构一个FORK语句产生一个新的并发进程的路程,并行进程在其结尾使用JOIN语句。当原进程和新产生的进程都达到JOIN语句后,代码的执行继续以
6、顺序方式进行。,UNIX重量级进程,UNIX操作系统基于进程的概念设计。单处理器时处理器被多个进程分时共享;处理器的使用从一个进程切换到另一个进程。(切换过程中可能出现停滞等问题)在多处理机系统中,进程的执行可以真正地并发。UNIX系统调用fork()来创建新进程。除了进程ID外,被创建的新进程是调用进程的完全拷贝。,线程,UNIX fork创建的进程是一个“重量级”进程;它是一个完全独立的新进程,拥有自己的变量、栈和存储器分配。更高效的机制是指定并发例程共享相同的存储器空间和全局变量的机制。通过thread或lightweight process实现。,(a)进程,(b)线程,进程和线程之间
7、的区别,编程工具代表:Pthread:POS thread 简称为pthread,Posix线程是一个POS标准线程。该标准定义内部API创建和操纵线程。POSIX线程具有良好的可移植性,Solaris、Linux、Windows等平台均可应用。Pthreads定义了一套C程序语言类型、函数与常量。以pthread.h头文件和一个线程库实现。OpenMP:用于共享内存并行系统的多线程程序设计。支持编程语言C、C+和Fortran。OpenMP提供对并行算法的高层的抽象描述,程序员通过在源代码中加入专用的pragma来指明自己的意图,由此编译器可自动将程序并行化,并在必要处加入同步互斥以及通信。
8、(若不加入pragma或编译器不支持,则程序退化为串行程序,可正常执行,但无法利用多线程加速程序执行),3消息传递编程(Message Passing),概况:在消息传递模型中,驻留在不同节点上的进程可以通过网络显式地传递消息相互通信,实现进程之间的信息交换、协调步伐、控制执行等。MPP,COW的自然模型,也可应用于共享变量多机系统,适合开发大粒度的并行性特点:多线程异步并行性分开的地址空间显式相互作用显式数据映射和负载分配常采用SPMD形式编码,编程工具代表:PVM:并行虚拟机(Parallel Virtual Machine)是一种常用的基于消息传递的并行编程环境,它把工作站网络构建成一个
9、虚拟的并行机系统,为并行应用提供了运行平台。支持WindowsNT等非Unix平台,程序设计语言支持C、Fortran和Java。MPI:消息传递接口(Message Passing Interface)是一个基于消息传递的并行编程工具。它具有移植性好、功能强大、效率高等优点,且有多种免费、使用的实现版本。MPI是1994年5月发布的一种消息传递接口。它实际上是一个消息传递函数库的标准说明,以语言独立的形式来定义这个接口库,并提供了与C、Fortran以及JAVA语言的绑定。,共享存储和消息传递程序设计模型对比实例:计算的样本程序,计算的串行程序(C语言),#include#define N
10、1000000main()double local,pi=0.0,w;long i;w=1.0/N;for(i=0;iN;i+)temp=(i-0.5)*w;pi=4.0/(1.0+temp*temp)+pi;printf(“pi is%f n”,pi*w);,N次循环,每次对pi累加,计算的并行程序(共享存储模型),#include static long num_steps=100000;double step;#define NUM_THREADS 2;void main()int i;double x,pi,sumNUM_THREADS;step=1.0/(double)num_ste
11、ps;omp_set_num_threads(NUM_THREADS)#pragma omp parallel double x;int id;id=omp_get_thread_num();for(i=id,sumid=0.0;i=num_steps;i=i+NUM_THREADS)x=(i-0.5)*step;sumid+=4.0/(1.0+x*x);for(i=0,pi=0.0;iNUM_THREADS;i+)pi=sumi*step;,/开始线程分配,并行执行,/头文件,嵌入C或C+,当一个线程运行到parallel指令时,它会创建一个线程组并成为该组进程的主线程。主线程线程号为0。当
12、并行域开始时,程序代码被复制,每个线程都会执行该代码。到并行部分结束时,只有主线程越过路障继续执行。,OpenMP是基于线程的并行编程模型,一个共享存储的进程由多个线程组成。OpenMPI使用FORK-JOIN并行执行模型。,所有的OPENMP程序开始于一个单独的主线程(Master Thread)。主线程会一直串行地执行,直到遇见第一个并行域(Parallel Region)才开始执行。接下来过程如下(1)FORK:主线程创建一队并行的线程,然后并行域中的代码在不同的线程队中并行执行;(2)JOIN:当诸线程在并行域中执行完之后,它们或被同步或被中断,最后只有主线程执行。,编写OpenMP程
13、序,开发工具已增加了对OpenMP的支持,Visual Studio 2005完全支持OpenMP编写OpenMP程序的必要步骤:(1)生成项目(2)配置项目,支持OpenMP(3)加入头文件#include“omp.h”(4)编写源程序;(5)配置环境变量,确定线程的数目(6)执行程序,计算的并行程序(消息传递模型),#include#define N 100000 main()double local=0.0,pi,w,temp=0.0;long i,taskid,numtask;w=1.0/N;MPI_ Init(&argc,&argv);MPI _Comm _rank(MPI_COMM
14、_WORLD,&taskid);MPI _Comm _Size(MPI_COMM_WORLD,&numtask);for(i=taskid;i N;i=i+numtask)temp=(i-0.5)*w;local=4.0/(1.0+temp*temp)+local;MPI_Reduce(&local,&pi,1,MPI_Double,MPI_SUM,0,MPI_COMM_WORLD);if(taskid=0)printf(“pi is%f n”,pi*w);MPI_Finalize();/*main()*/,/头文件,嵌入C或C+等,/初始化MPI环境,/MPI进程个数和编号,/MPI归约操作
15、,消息传递模型中各个进程只能直接访问其局部内存空间,而对其他进程的局部内存空间的访问只能通过消息传递来实现。MPI初始化操作通过程序运行命令获取派生进程的数量。然后每个进程针对分配的不同的数据段执行相同的操作。最后使用reduce归约操作将结果在第0个进程中进行求和。(归约操作属于群集通信操作的一种形式),三种计算模型特征比较,2.2 消息传递编程基础,(1)编程选择 对于消息传递计算机编程可用以下方法进行:(1)设计一种专用的编程语言。如occam语言,专为Transputer消息处理器设计(2)对于现有的一种顺序高级语言的语法/保留字加以扩展来处理消息传递。如CC 和Fortran M(3
16、)使用现在的一种顺序高级语言,但为它配备一个能进行消息传递外部过程库。常用方法C Fortran等均可.,采用C语言,以能进行消息传递的消息传递库调用对其加以扩充,以完成进程对进程的直接消息传递。这种方法中,必须显式地说明执行哪些进程,何时在并发进程间传递消息,以及传递什么消息。这类消息传递系统必须使用两个基本方法:(1)创建分离进程以使它们能在不同的计算机上执行的方法(2)发送和接收消息的方法,2)进程创建方法 创建进程有静态和动态两种方法。在静态进程创建时,所有进程在执行前必须加以制定,系统将执行固定数据的进程。程序员通常需在进程或程序执行前用命令行显式标识它们。,在大多数应用中,进程不会
17、全相同也不会全不同;通常有一个称为主进程(master)的控制进程,其余的进程为从进程(slave),这些进程本质上相同,融合在SPMD模型中。SPMD模式的编程是最常用的消息传递系统之一MPI中最常采用的方法。,动态进程创建最通用的模型是MPMD,需要为不同的处理器编写完全独立的不同程序。通常采用主从方法是一个处理器执行主进程,而其余进程由主进程启动。pvm中的spawn(name_of_process)函数。调用后立即启动另一个进程,此后调用进程和被调用进程两者一起向前执行。派生的进程必须是事先编译好的,且可执行的程序。,在动态进程创建方法中,可在其它进程的执行期间创建进程并启动执行它们。
18、通常用进程创建构造或库调用创建进程,也可对进程撤销。动态进程创建比静态进程创建功能更强大,但会导致显著的开销。,(3)消息传递方法 发送和接收消息传递库的调用基本形式如下:send(parameter_list)recv(parameter_list)其中send()出现在源进程中,由它发送消息;而recv()出现在目的进程中收集已被发出的消息;括号中的参数依赖于软件。简单的调用如:send(recv(&y,source_id),我们已经了解如何从一个执行的源进程向一个特定的目的进程发送消息,这里的目的进程的发送例程中是作为一个参数给定的,而源是在接收例程中作为一个参数给定的。目的进程中的re
19、cv()将只接收recv()中以参数指明的源进程所发来的消息,对其他消息将不予接收。也可以使用1作为源地址的通配符,允许目的进程接收来自任何源进程的消息。为了提供更大的灵活性,可以附于消息的消息标记(message tag)对发送得来消息加以选择。消息标记msgtag是一个典型的由用户选定的正整数,对发送来的不同类型的消息加以区分。send(,消息传递的其他方法,对拥有消息源的进程通常要求它将相同消息发送给多个目的进程。广播(broadcast):指向所有与求解问题有关的进程发送相同的消息。汇集(gather):指一个进程从一组进程中的每一个进程收集一个值。散播(scatter):用于描述根进
20、程中数据数组中的每个元素分别发送给各个进程。,广播操作,汇集操作,散播操作,2.3 MPI编程,2.3.1 最简单的MPI并行程序MPI(Message Passing Interface)是1994年5月发布的一种消息传递接口,即基于消息传递的并行编程工具。它具有移植性好、功能强大、效率高等优点,且有多种免费、使用的实现版本如MPICH、LAM、CHIMP等。它实际上是一个消息传递函数库的标准说明,以语言独立的形式来定义这个接口库,并提供了与C,JAVA,FORTRAN语言的绑定。MPI不是一个独立的自包含系统,而是建立在本地并行程序设计环境之上,其进程管理和I/O均由本地并行程序设计环境提
21、供。参考文献:高性能计算之并行编程技术 MPI并行程序设计 都志辉 编著,MPI程序的一般结构,MPI程序的执行过程,Hello Parallel World-最简单的MPI程序,/*文件名 hello.c*/#include“mpi.h”#include Int main(int argc,char*argv)MPI_Init(/并行部分结束,两个节点运行结果:hello parallel world!hello parallel world!,(1)并行初始化函数:int MPI_Init(int*argc,char*argv)通过MPI_Init函数进入MPI环境并完成所有的初始化工作。
22、argc为变量数目;argv为变量数组,两个参数来自main函数的参数,因此并行程序中main函数的参数不可缺少。必须调用;首先调用;调用一次。,MPI的函数一般都以MPI_开头,所有的MPI并行程序必须包含mpi.h头文件。,(2)并行结束函数:int MPI_Finalize(void)通过MPI_Finalize函数从MPI环境中退出,释放MPI的数据结构及操作。该语句之后仍然可以进行串行程序的运行。该函数一旦被应用程序调用时,就不能调用MPI的其它例行函数(包括MPI_Init),用户必须保证在进程调用MPI_Finalize之前把与完成进程有关的所有通信结束,所有并行程序均为这样的结
23、构,其中main函数的参数argc和argv分别为程序输入参数个数及输入参数数组。开始和结束函数之间就是程序的并行部分,将在所有节点上获得执行。,#include int main()printf(“hello parallel world!n”);这种环境下进程没有MPI环境的支持,无法对自己进行识别和进行节点间的数据通信,因此无法完成真正的并行计算。只有开始和结束函数之间的程序才具备进行消息传递模式的并行程序设计的能力。,2.3.2 获取进程标志和机器名,并行程序设计需要协调大量的计算节点参与计算,且需要将任务分配到各个节点并实现节点间的数据和信息交换。因此各个进程需要对自己和其它进程进行
24、识别和管理,每个进程都需要有一个唯一的ID,从而实现大量计算节点的管理和控制,有效完成并行计算任务。因此获取进程标识和机器名是MPI需要完成的基本任务,各节点根据自己的进程ID判断哪些任务需要自己完成。,(1)获取当前进程标识函数,int MPI_Comm_rank(MPI_Comm comm,int*rank)调用该函数获得当前进程在指定通信域中的进程号(0 进程数-1)。一个进程在不同通信因子中的进程号可能不同。Comm为该进程所在的通信域句柄,rank为调用该函数返回的进程在通信域中的标识号。一般对于comm参数,采用MPI_COMM_WORLD通信域。它是MPI提供的一个基本通信域(默
25、认),在这个通信域中每个进程之间能相互通信,也可以建立自己的通信域。,(2)获取通信域包含的进程总数函数,int MPI_Comm_size(MPI_Comm comm,int*size)不同进程通过调用该函数获取指定通信域的进程个数,确定自身完成任务比例,显然这里的通讯因子必须是组内通讯因子。Comm为通信域句柄,size为函数返回的通信域comm内包含的进程总数。,(3)获取本进程的机器名函数,int MPI_Get_processor_name(char*name,int*resultlen)name为返回的机器名字符串,resultlen为返回的机器名长度。,/*例程分析:who.c*
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 并行 程序设计
链接地址:https://www.desk33.com/p-248459.html