1OpenMP并行编程(一)——并行编程介绍——并行域与工作共享2内容提要并行编程OpenMP简介OpenMP编译制导OpenMP库函数OpenMP环境变量OpenMP示例3并行程序设计模型隐式并行(ImplicitParallel)数据并行(DataParallel)共享变量(SharedVariable)消息传递(MessagePassing)并行程序设计模型4隐式并行编写串行程序通过编译器和运行支持系统将串行程序自动并行化特点:语义简单,可移植性好,易于调试和验证缺点:细粒度并行,效率很低隐式并行5数据并行SIMD(单指令流多数据流)同一操作同时作用到一组数据上特点:单线程,单一地址空间,编程简单,松散同步,隐式交互,隐式数据分配缺点:并行粒度局限于数据级并行,粒度小典型代表:Fortran90,HPF数据并行SIMD:SingleInstructionMultipleData6共享变量适用于SMP和DSM特点:松散同步,多线程(SPMD,MPMD)单一地址空间,显式同步,隐式通信,隐式数据分布典型代表:OpenMP,Pthreads共享变量SPMD:SingleProgramMultipleDataSMP:SharedMemoryProcessorsDSM:DistributedSharedMemoryMPMD:MultipleProgramMultipledataPthreads:POSIXthreadsOpenMP:OpenMulti-Processing7消息传递MPP、COW的自然模型特点:异步并行,多线程,多地址空间,显式同步,显式通信,显式数据映射和负载分配典型代表:MPI,PVM消息传递MPI:MessagePassingInterfaceCOW:ClusterofWorkstationsPVM:ParallelVirtualMachineMPP:Massivelyparallelprocessing8并行编程模型数据并行:Fortran90,HPF;适用于SMP,DSM共享内存:OpenMP,Pthreads;适用于SMP,DSM消息传递:MPI,PVM;适用于所有并行机并行编程模型标准三者可混合使用9并行化方法相并行(PhaseParallel)流行线并行(PipelineParallel)主从并行(Master-SlaveParallel)分而治之并行(DivideandConquerParallel)工作池并行(WorkPoolParallel)基本并行化方法10并行化方法一组超级步(相)步内各自计算步间通信同步方便差错和性能分析计算和通信不能重叠相并行CCCSynchronousInteractionCCCSynchronousInteraction............将分成一系列子任务t1,t2,…,tm,一旦t1完成,后继的子任务就立即开始,并以同样的速率进行计算一组进程,流水线作业,流水线设计技术流行线并行P1P2Pn......11并行化方法主进程:串行,协调任务子进程:计算子任务与相并行结合主进程易成为瓶颈主从并行SlaveSlaveSlaveMaster...分而治之将问题分解成若干特征相同的子问题,分而治之父进程把负载分割并指派给子进程重点在于归并难以负载平衡12并行化方法初始状态:一件工作进程从池中取任务执行可产生新任务放回池中直至任务池为空易于负载平衡工作池并行WorkPoolP1P2Pn...13并行算法设计原则与体系结构相结合具有可扩展性粗粒度减少通信优化性能并行算法设计基本原则粒度是指各个线程可以独立并行执行的任务的大小,是一个相对的概念,与并行度和并行机相关。一般可理解为:细粒度:基于向量和循环系级并行中粒度:较大的循环级并行大粒度:任务级并行(如:区域分解)ParallelProgrammingParadigms14并行程序设计步骤划分(Partitioning)将计算任务划分成尽可能多的小任务划分方法主要有:数据分解(区域分解)和功能分解通信(Communication)确认各任务间的数据交流,评估任务划分的合理性组合(Agglomeration)依据任务的局部性,将小任务组合成大任务,减少通信映射(Mapping)将组合后的任务分配到各个线程,力争负载平衡并行程序设计步骤15内容提要并行编程OpenMP简介OpenMP编译制导OpenMPAPI函数OpenMP环境变量OpenMP示例16OpenMP简介OpenMP是基于共享存储体系结构的一个并行编程标准。OpenMP通过在源代码(串行程序)中添加OpenMP指令和调用OpenMP库函数来实现在共享内存系统上的并行执行。OpenMP为共享内存并行程序员提供了一种简单灵活的开发并行应用的接口模型,使程序既可以在台式机上执行,也可以在超级计算机上执行,具有良好的可移植性不打开OpenMP编译选项,编译器将忽略OpenMP指令,从而生成串行可执行程序打开OpenMP编译选项,编译器将对OpenMP指令进行处理,编译生成OpenMP并行可执行程序并行线程数可以在程序启动时利用环境变量等动态设置支持与MPI混合编程17OpenMP简介起源于ANSIX3H5(1994)标准由设备商和编译器开发者共同制定,工业标准(1997)编程简单,增量化并行,移植性好,可扩展性好支持Fortran,C/C++(编译器自带OpenMP)()支持Unix,Linux,Windows等操作系统AMD,Intel,IBM,Cray,NEC,HP,NVIDIA,......TheOpenMPAPIsupportsmulti-platformshared-memoryparallelprogramminginC/C++andFortran.TheOpenMPAPIdefinesaportable,scalablemodelwithasimpleandflexibleinterfacefordevelopingparallelapplicationsonplatformsfromthedesktoptothesupercomputer.API:ApplicationProgrammingInterface18OpenMP运行模式OpenMP是基于线程的并行编程模型OpenMP采用Fork-Join并行执行方式OpenMP程序开始于一个单独的主线程(MasterThread),然后主线程一直串行执行,直到遇见第一个并行域(ParallelRegion),然后开始并行执行并行域。并行域代码执行完后再回到主线程,直到遇到下一个并行域,以此类推,直至程序运行结束。是下面三种编程要素的集合:编译制导(CompilerDirective)运行库函数(RuntimeLibraryRoutines)环境变量(EnvironmentVariables)19Fork-JoinFork:主线程创建一个并行线程队列,然后,并行域中的代码在不同的线程上并行执行Join:当并行域执行完之后,它们或被同步,或被中断,最后只有主线程继续执行FORKJOINFORKJOIN并行域可以嵌套并行域并行域串行域串行域串行域20Fortran举例programhellouseomp_libimplicitnoneinteger::tid,nthreads!$ompparallelprivate(tid)tid=omp_get_thread_num()write(*,100)Hello,worldfromOpenMPthread,tidif(tid==0)thennthreads=omp_get_num_threads();write(*,100)Numberofthreads,nthreadsendif!$ompendparallel100format(1X,A,I1,/)endOpenMP编译制导指令标识符!$omp模块:omp_lib编译gfortran–fopenmphello.f90ifort–openmphello.f9021C举例#includeomp.h#includestdio.hintmain(){intnthreads,tid;#pragmaompparallelprivate(nthreads,tid){tid=omp_get_thread_num();printf(Hello,worldfromOpenMPthread%d\n,tid);if(tid==0){nthreads=omp_get_num_threads();printf(Numberofthreads%d\n,nthreads);}}return0;}OpenMP编译制导指令标识符#pragmaomp头文件:omp.h编译gcc–fopenmphello.c22OpenMP说明在Fortran程序中,所有OpenMP编译制导指令都是以!$OMP开头,后面跟具体的指令,一般形式为(FORTRAN77程序中以C$OMP或*$OMP开头)指令标识符必须位于所在行的最前面,字符之间不能有空格标识符与指令之间必须用空格隔开,每行只能有一个OpenMP指令OpenMP指令不区分大小写(Fortran)所有OpenMP编译指令都必须以标识符开始续行的行首要有标识符,后面可以跟续行符&字句为可选,若有则必须出现在指令之后若有多个字句,则用空格隔开,顺序任意几点说明(Fortran)!$OMP编译制导指令[字句(clause)]23OpenMP说明增量并行:逐步改造现有的串行程序,每次只对部分代码进行并行化,这样可以逐步改造,逐步调试。C/C++的指令标识符为#pragmaompC/C++程序中,OpenMP指令区分大小写每个OpenMP指令后是一个结构块(用大括号括起来)几点说明(C/C++)OpenMP并行程序编写方法OpenMP源程序的编译gcc–fopenmphello.cicc–openmphellp.cgfortran–fopenmphello.f90ifort–openmphello.f90ifort–openmp–Tf–freehello.f95!ifort不认.f9524编译制导并行域指令:生成并行域:即产生多个线程以并行执行任务,所有并行任务必须放在并行域中才可能被并行执行工作共享指令:负责任务划分,并分发给各个线程工作共享指令不能产生新线程,因此必须位于并行域中同步指令:负责并行线程之间的同步数据环境:负责并行域内的变量的属性(共享或私有),以及边界上(串行域与并行域)的数据传递编译制导指令大致分四类OpenMP通过对串行程序添加编译制导指令实现并行化25编译制导指令PARALLELENDPARALLEL标识一个并行域的开始和结束并行域指令ParallelConstructs负责产生多个线程,即生成一个并行域并行域中的所有代码默认都将被所有线程并行执行可以通过线程id给不同线程手工分配不同的任务也可以利用工作共享指令给每个线程分配任务26编译制导指令工作共享指令Work-SharingConstructsDOENDDO用在DO循环之前,标识一个并行循环任务的开始和结束,必须保证每次循环之间无数据相关性SECTIONSSECTIONENDSECTIONS标识仅由一个线程执行的若干区域的开始标识仅由一个线程执行的一个区域标识仅由一个线程执行的若干区域的结束SINGLEENDSINGLE标识仅由一个线程执行的区域开始和结束WORKSHAREENDWORKSHARE用于Fortran95中可并行执行的语句,如FORALL结构,WHERE结