资 源 简 介
Parallel_Programming_in_Fortran95_using_OpenMP中文版 pdf设置计算机、设置(1)在ws2008中新建 fortran控制台程序,选择项目( Projcct)->属性( property)- Fortran→>语言( Language),在 Process OpenMP Directives选项中选择 Generate Parallel Code( Openmp),rOp点击确定以打开 OpenMP支持。(2)设置环境变量:我的电脑->属性>高级→>环境变量,在系统变量栏中新建一个OMP NUM THREADS变量,值设为2,即为程序执行的线程数(线程数一般设为处理器核数)运行如下代码program testISOMP PARALLELprint*ISOMP END PARALLELEnd progra行结果第一章 OpenMP Fortran应用程序接口界1.1简介为获得史强的计算能力,计算系统的开发人员开始考虑联合使用多个计算机,这就是并行机的起源,为程序员及硏究者开启了新的斫究领域。如今,并行计算杋在科研领域较为普遍,广泛应用于复尔计算,如模拟原了弹爆炸,蛋白质聚合以及水流扰动。并行机面临的一大挑戕是开发一套可用于有效硬件的代码,以便在更短的时间内解决大型问题。但由」存在各种不同的硬件构架,并行编程可不是一件容易的事情。主要有两个系列的并行机可以被识别内存共享结构( Shared- memory architecture):基于一组可访问共同内存的处理器,这种构架的计算机使用SMP( Symmetric Multi Processing)机器指令,即对称多进程分布式内存结构 Distributed-memory architecture):每个处理器拥有私有的内存,处理器之间通过消息( Messages)进行信息交换。集群( clusters通常被用于这类计算设备每个系列都有自己的优缺点,并行编程标准试着针对某一构架充分利用其优点。近年米出现了一种新的行业标准,旨在为共享内存机器上开发并行程序建立良好的基础,这就是 OpenMP。1.11历史回顾共享内存机存在很久了。过去的每个硬件厂商都有自己的指令和库标准,允许程序使用指定的并行机。早期的标准 ANSI3H5未被正式米用,一方面是因为没有使件商的大力支持;另一方面,分布式存储机拥有自己的标准消息传递库PVM和MPI,能很好地代替内存共享机但在1996-1997年,出现了内存共亨编程接口界面,引起了广泛的兴趣,主要因为:(1)硬件商恢复了对共享内存构架的兴趣(2)部分丿商认为,使用消息传递接口的并行程序冗长、耗时,需要更简单的编程接口很多硬件商和编译器公司都把 OpenMP看作行业标准:它定乂的一系列编译器指令、运行斥和环境变量可用于 Fortran和CC-的共享内仔式并行编程OpenMP整合为简单的语法,不支持早期的共享内存指令集处理 coarse-grain parallelism(将目标域分解为子域,交由多个处理器进行计算)。过去,由于对 coarse-grain的支持有限,廾发者认为共亨内存并行编程对ine- grain parallelism(分解循环到多个处理器进行迭代)的支持也是有限的。1.12参与者OpenMP规范由 OpcnMP Archi-tccturc Rcvicw Board拥有、编写和维护,很多公司积极参与共亨内存编程接口界面标准的开发。2000年, OpenMP ARB的永久性合作者有:US Department of Energy, through its ASCI program(关国能源部)Compaq Computer Corp(康柏电脑公司)Fujitsu(日本富士通)Hcwlctt-Packard Company(惠普)Intel Corp.(英特尔)International Business machines(国际商业机器公司)Kuck& Associates,Inc.(擅于并行软件开发,2000年被 intel l收购)· Silicon Graphics Incorporate(硅谷图形(美国计算机公司))· Sun Microsystems(sun微系统公司)此外,还有很多公司在他们的程序或编译器里使用OpεnMP的同吋,通过提交错误报告、评论和建议等方式,对 OpenMP ARB做出了很多的贞献。113关于本文档本文档只在为有兴趣学习 OpenMP的 Fortran95程序员提供基本的帮助。 OpenMP ARB发布的 OpenMP规范中未详细说明的尤为重要的部分及不同 OpenMP指令和子句的性能比较,在本文档中都带有图示。为使文档简练, OpenMP的部分内容未予列出,建议读者同时阅读木文档和 OpenMP规范。本文档只考虑 Fortran95编程语言,尽管大部分概念和观点也适用于 Fortran77。作者认为 fortran95优于 Fortran77,而且良好的编程方法非常重要,本文只提供部分与上述编程理念一致的 OpenMP特性。因为本文提到的概念只是作者自己的观点,因此读者需要另外阅读完整 OpenMP规范现有的关」 OpenMP的文档不多,木文档叫在网上免费发布,但作者保有版权。欢迎对本文内容进行评论,鼓励读者提交建设性的意见和建议拱写本文档期间(2001冬-2002春),编译器仗用两个不同的 OpenMP规范:v.和v20后者是前者的升级版,有必要区分每个版本的有效内容。本文中蓝色字体部分的内容仅适用12基础OpenMP代表一个关于编译器指令、运行库和环境变量的集合,用于在共享内存机器上进行并行稈序开发,集合中的每个元素将用一章进行说明。在回顾有效编译器指令之前,有必要学习 OpenMP的基础知识。尽管称为“棊础”,这部分内容却是 OpenMP的基本部分,允许在程序中包含 OpenMP命令和破坏并行运算的代码块。12.1 OpenMP指令和条件编译的标记OpenMP标准的目的之一,就是使相冋的代码段既可以运用于支持 OpenMP的编译器上,又可以运用于普通编译器上。要获得上述效果,只有使普通编译器忽略 OpenMP指令和命令,而支持 OpenMP的编译器却可以发现它们。因此引入下面两条指令标元I SOMP.S因为首字符为感叹号“!”’,普通编译器将其解释为注释行,并忽略其內容。但是支持OpenMP的编译器叫以识别所有序列,并进行如下操作:!$OMP: OpenMP编译器获知本行的余下信息为 OpenMP指令。通过在以后的代码行之前设置同样的标记和使用标准 Fortran95方法限制代码行,可以将 OpenMP指令扩展到多行代I SOMP PARALLEL DEFAULT(NONE) SHARED(A, B) PRIVATE(C, D)&I SOMP REDUCTION(+: A)指令标记符!$OMP和后面的 OpenMP指令之间必须有至少一个空格,否则指令标记不能破正确识别,此行将当作注释行。!$:与条件编译相关的行,表示其后内容仅对 OpenMP编译器有效。这种情况下,标记的两个字符被两个空格替代,绵译尜将会考虑本行内容。正如前面的例子,可以将源代码行扩展到多行I S interval- L*OMP get thread num(/&. S(OMP get num threads(-1)再次强调,在条件编译指令!$和其后的源代码之间必须包含至少一个空格,否则条件编译指令无法止确识别,此行将当作注释行两个指令之前可以包含任意数量的空格,且只能为空格,否则将会被解释为注释行。122并行区域构造函数OpenMP最重要的指令就是定义并行区域,这个区域是将由多线程并行执行的代码块并行区域需要创建/开和销毁/关闭,需要用到两个指令组成的指令对:I SOMP PARALLELwrite(, )"Hello"I SOMP END PARALLEL指令对之间的代码会被每一个线程执行,并行区使用了多少线程,“Iell”将会在屏幕上出现多少次。并行区之外的代码只由单一线程执行,与串行程序的一般行为是一致的,因此它们被称为串行区域当止在执行串行区域的线程遇到并行区域时,它将创建·组新线程,自身成为其中的主线程。主线程是线程组中的一员,也参与执行计算。并行区域的每一个线程都有唯一的线程号,编号从0到Np-1,其中0为主线程,Np为线程总数。图1.阐明了前面示例的运行方式。thread oserreglonExccutionareadthread 1thread mparallel regionwrite(*, *)"Hello" write(*, *)"Hello"write(*,*)"HelloFigure 1. 1: Graphical representation of the example explaining the working principle of the!SOMP PARALLEL/!$OMP END PARALLEL directive-pair在并行区域的开始部分,可以增加子句以限定并行区域的执行方式:如变量作用域、线程数、对某些变量的特殊处理等,形式如下I SOMP PARALLEL clausel clause2I SOMP END PARALLEL并不是所有在第三章详解的子句都可用于 Opening指令,只有以下部分PRIVatE(list): see page 37SHARED( list): see page 38DEFAULT(PRIVATE SHARED NONE ): see page 39FIRSTPRIVATE( list): see page 40COPYIN(list): see page 42REDUCTION(operator: list ) see page 43IF( scalar logical expression): see page 46NUM THREADS(Scalar integer expression): see page 47!$ OMP END PARALLEI表示并行区域的结束至此,每个线程里的局部变量( PRIVATE都将释放,主线程继续执行并行区域后面的内容,其他线程将被刖除。关闭并行区之前,主线程将等待所有其他线程执行完毕;否则数据将会丢失或者工作不能完成。这个等待在并行运行的线程之间是同步的,因此! SOMP END PARALLEL指令隐含着同步性当代码证包含并行区域时,为确保最终程序符合 OpenMP规范,必须满足两个条件:/(1) SOMP PARALLEL clausel clause22/!$ OMP END PARALLEL指令对必须出现在程的同一文件中;(2)并行区域内的代码必须为结构化代码,即不能跳入或珧出并行区,如使用GOTO语句。除了以上两个规则,没有其他的限制条件。尽管如此,在使用并行区域的吋候也得小为即使考虑上述限制条件,也可能得到不正确的程序。直接置于指令对!$ OMP PARALLEL clausel clause2/!$ OMP END PARALLEL之间的代码块称为指令对的词法范围( lexical extent)。词法范围内的代码及其调用的代码均称为指令对的动态范闱( dynamic extent),例如:I SOMP PARALLELwrite(, )"Hellocall be friendlyI SOMP END PARALLEL此例中,子程序 be friendly包含的代码是指令对动态范围的一部分,但不属于词法范围。这两个概念非常重要,因为前面提到的子句中,有些只能用于词法范围,有些月于动态范围。可以将平行区域嵌套到另个平行区域。如果平行队列里的个线程遇到另个平行区域,它将创建新的线稈组,本身称为新线程组中的主线稈。第二个平行区域称为嵌套平行区域,示例如下:I SOMP PARALLEIwrite(, ")"HellI SOMP PARALLELriteI SOMP END PARALLELI SOMP END PARALLEL假设每个平行区域都使用Np个线程,总共将有Np2+Np个消息出现在屏幕上。结果的树状结构如图1.2。thread oI seral region--------+------------------EI parallel regionthread othread 1HelloHelloxecution------1-------nested parallel thread o thread 1 11 thread 0 thread 1I regionsHiHiHiHiFigure 1.2: Graphical representation of the example explaining the concept of nested parallelregions.第二章 OpenMP构件如果只有并行区域构件存在,所有线程只可能执行完全相同的任务,但这并不是并行的目的。因此, OpenMP定义了史多的构件,允许将一个任务分派给不同的线程,以生成一个真正的并行计算程序OmMP指令或构件存在四种不同的群,每个样有不同的目的。选择群中的哪一个指令决于待解决问题的性质。只有了解了每一个指令的使用原则才能执行正确的选择。21 Work-sharing构件第一个 OpenMP指令集意在将特定任务分解为片段,将一个或多个片段传送给每一个并行线程。这样,原本在串行程序里由单一线程执行的任务,分配给一组线程,得到更快的执行程序(要求处理器数量大于l。如果只有一颗处理器,多线程并行计算比串行计算更慢)。所有的work- sharing构件都必须置于平行区域的动态范围( dynamic extends)内才有效。如若不是这种情况, work-sharing构件也会执行,但线程组中只有一个线程会执行,原因是work- sharing构件不会创建新线程;它是!$ OMP PARALLEL/$ OMP END PARALLEL指令对中的任务使用work- sharing构件有如下限制(1)work- sharing构件必狈被所有线程执行或者没有任何线程执行(2)work- sharing构件必须依次被线程组中的线程执行在关闭指令处,所有 work-sharing构件都是隐式同时的。一般情况下,需要确认的一点是:在work- sharing构件之后的代码所请求的所有信息是最新的。但这种线程同时性并不总是必要的,因为这是一种浪费资源的事情(等待所有线程到达后才继续执行后续代码),因此需要一种抑制机制。在关闭指令后连接一特定子句 NOWAIT。关于 NOWAIT的更多信息见第三章。2.1.1 ! SOMP DO/SOMPEND DO指令对使最近的do循环并行执行。例如:I SOMP DOdoi=1.1000I SOMP END DO将do循环分散到不同的线程:每个线程仅计算部分迭代。如,有10个可用线程,一般每