openmp并行编程_OpenMP编程初步(Fortran语言)

目前最主流的将CPU程序并行化的手段是OpenMP和MPI。OpenMP是线程级并行,共享内存,但不能跨节点并行。MPI进程级并行,分布式内存,可跨节点并行。在程序编写的复杂程度上,OpenMP只需在串行程序上做少许的改动即可实现并行,而MPI的编程往往比较复杂,一般与串行程序是两套不同的代码。

本文简单介绍Fortran语言下使用OpenMP实现并行的方法。话不多说,直接上一个简单的例子:

7a08d4d37045acd07e1fe51bdc83f9af.png

在上述程序中,以!$omp开头的语句称为编译指导语句,控制程序的并行。注意到,这些语句是以!开头,对普通的Fortran程序而言实际上是注释语句。因此,如果我们用常规的ifort XXX.f90的方式编译,这就是一个串行的程序,而如果加上-qopenmp选项(不同编译器的选项名称不同),则会将22-28行间的程序并行。这就是OpenMP的强大和方便之处!

一段程序是否可以并行化,就要看假设并行之后,各并行部分之间是否有数据竞争,如果没有数据竞争,或通过算法的改进可以消除数据竞争,则这段程序可以并行化。很明显,上述示例是一个矩阵乘法的例子,A矩阵与B矩阵相乘得到C2矩阵。经过分析,C2矩阵的每一行之间是不存在数据竞争的,因此可以按C2的行进行并行化。下面仔细说明一下以上程序中的编译指导语句的含义。

在并行程序中,最多的并行便是对循环的并行,因此在需要并行的循环前后写上!$omp parallel do,在循环结束后写上!$omp end parallel do,若需要分行,自由格式中在每句的末尾加&,续行的开头依旧要写上!$omp;固定格式中,在第二行的第6列写上&之类的非空白字符,表示接续上一行。

以default、schedule、private等开头的句子称为子句。其中schedule表示任务的调度类型,常用的有static、dynamic和guided三种,具体区别以后会专门介绍。在循环中,变量可分为两大类:各线程共享的变量,为shared类型;各线程私有的变量,为private类型。一般可根据程序中两种类型的数据的多少,将多的定为default类型,这样只要将少的一部分定义在另一种类型中,比如,本例中,C2、A、B、m、n为各线程共享,i、j、k为各线程私有。具体哪些变量为共享,哪些为私有,是OpenMP编程的关键之一,在变量很多的时候尤其要仔细区分好类别。有了以上简单介绍,大家应该可以写出最简单的OpenMP并行程序了。下面我们来看看程序的运行效率。同时,我们用Fortran内置的matmul函数进行对比。

  1. 编译时不加-qopenmp,则程序为串行程序,自写的矩阵相乘与matmul所用时间相同,均为64秒。

  2. 编译时加上-qopenmp,则程序为并行。笔者所用机器的CPU为4核的i7处理器,程序运行时可以看到CPU使用率为400%。此时并行部分所用时间为43秒。并行效率似乎有点低,4核并行时间不能变成理想的1/4,但也不应该这么低。分析一下程序,根据二维数组在内存中的存储,如果将ij循环对调,效率会提高。果真结果变为20秒,速度竟然提升了一倍!

本文所述的是最简单的并行方法,更多的功能会在以后分享给大家。使用Fortran语言的同学可以参考雷洪、胡许冰著的《多核并行高性能计算OpenMP》一书,这似乎是市面上唯一的基于Fortran语言的OpenMP教材。而使用C语言的同学,可参考的资料就比较多了。

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值