《OpenACC并行编程实战》—— 第3章 OpenACC计算构件 3.1 条件编译

简介: 程序的加速效果来自于对计算部分的并行化。本章重点介绍计算并行化所用的3个构件:kernels、loop和parallel,以及几个重要的子语。编译器将串行循环映射成并行线程的方式多种多样,需要仔细观察几种常用循环的并行化方式,掌握映射规律。

本节书摘来自华章出版社《OpenACC并行编程实战》一 书中的第3章,第3.1节,作者何沧平,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

第3章 OpenACC计算构件

程序的加速效果来自于对计算部分的并行化。本章重点介绍计算并行化所用的3个构件:kernels、loop和parallel,以及几个重要的子语。编译器将串行循环映射成并行线程的方式多种多样,需要仔细观察几种常用循环的并行化方式,掌握映射规律。为了演示计算构件的语法和加速效果,3.7节移植常用的Jacobi迭代。
特别提醒:用OpenACC并行化程序的过程中,可能不会立即有加速效果,甚至计算并行化反而使整体运行时间延长。这是正常现象,增加的时间是主机与设备之间的数据传输,不必担忧,第4章会详细讲述如何缩短数据传输时间。
从本章开始,假定读者拥有Linux环境下日常操作、编译运行代码的基础,已经成功部署OpenACC开发环境。Linux入门教材推荐《鸟哥的Linux私房菜》。本书中所有示例代码均经过测试验证,测试环境有3种:

  • 1)笔记本电脑:英特尔CPU,英伟达GeForce GT 420m显卡,Windows 7操作系统,PGI Workstation 15.10。
  • 2)笔记本电脑:英特尔CPU,英伟达GeForce GT 420m显卡,Ubuntu 14.04操作系统,PGI Workstation 16.3。
  • 3)服务器:两颗英特尔至强CPU,两块英伟达Tesla K20m计算卡,Red Hat Enterprise Linux 6.2操作系统,PGI Workstation 16.3。

英伟达GeForce GT 420m拥有96个CUDA核心。默认使用第1种环境编辑、调试代码,使用第2种环境获取程序性能、绘制性能图形,第3种环境特别用于计算区域内的过程调用和6.6节单机多卡的情形。
对示例代码的讲述以C语言主为,如无特别需要,只列出Fortran版代码,不再讲述重复的语法、技巧。为便于讲述,每行代码都添加了行号,这些行号不是代码的组成部分。

3.1 条件编译

OpenACC规范要求支持它的编译器预定义一个宏_OPENACC,宏的值为yyyymm,其中yyyy是编译器所支持OpenACC版本的发布年份,mm是月份。当且仅当OpenACC导语功能打开时,编译器必须定义这个宏。OpenACC 1.0、2.0、2.5版本对应的宏值分别为201111、201306、201509。可以在程序中使用下列语句将宏_OPENACC的值输出到屏幕上:

printf("_OPENACC=%d\n", _OPENACC); /* C语言 */
print*, "_OPENACC=", _OPENACC     ! Fortran语言

结合程序语言的预处理语句,该宏可以增强代码的适应性,请看例3.1。

889f5cd70594241cdcea6704c6186a289fe863ee

例3.1第9行中的函数acc_get_num_devices(.)的作用是获取设备的数量,函数功能细节此处不必深究,它的原型包含在头文件openacc.h中,不支持OpenACC的编译器没有该头文件,因此在第2行使用#ifdef条件包含这个文件,否则不支持OpenACC的编译器遇到#include语句时将报错。若编译器支持OpenACC则编译第8~9行,若编译器不支持OpenACC则编译第11行。
使用不支持OpenACC的gcc编译器编译:
$ gcc comp1c.c  -o comp1c.exe
$ ./comp1c.exe
OpenACC is not supported.

使用支持OpenACC的PGI编译器编译,并打开支持选项,在拥有一块英伟达显卡的笔记本上运行,正确给出运行环境中的设备数量:

$ pgcc -acc  comp1c.c  -o comp1c.exe
$ ./comp1c.exe
Number of device: 1

PGI编译器的C语言编译程序是pgcc,选项-acc的作用是打开编译器对OpenACC的支持,从而有了编译器定义的宏_OPENACC,没有选

-acc的话,第3、8~9行会被忽略。
Fortran代码有个预编译小技巧:Fortran语言本身不支持#ifdef等预处理指令,因此要在正式编译前预处理一下,见例3.2。将Fortran源码文件的扩展名由通常的小写.f90改为大写的.F90,PGI编译器就会自动添加预处理过程。

7315860970ab04c320f1deddfa03f475306285bd

PGI编译器的Fortran语言编译程序是pgfortran,支持Fortran 77/90/95/2003多个版本。使用支持OpenACC的PGI编译器编译,并打开支持选项-acc,运行结果正确显示拥有1个设备:
$ pgfortran -acc -o comp1f.exe comp1f.F90
$ ./comp1f.exe
 Number of device:             1
相关文章
|
11月前
|
JavaScript
量子程序设计基础 | 量子程序编程实例
创建并输出Bell态观测量子线路。
96 0
量子程序设计基础 | 量子程序编程实例
|
C语言 Perl
西门子S7-1200有哪几种编程方法?什么是线性化编程、模块化编程、结构化编程?
今天我们来说一说西门子S7-1200有哪几种编程方法,给大家简单介绍一下什么是线性化编程、模块化编程和结构化编程。
西门子S7-1200有哪几种编程方法?什么是线性化编程、模块化编程、结构化编程?
|
Linux C++
嵌入式linux基础:c++(三)程序结构
嵌入式linux基础:c++(三)程序结构
134 0
嵌入式linux基础:c++(三)程序结构
|
存储 并行计算 程序员
初识openmp 编写简单程序并评价其性能
初识openmp 编写简单程序并评价其性能
初识openmp 编写简单程序并评价其性能
|
并行计算
CUDA C 最佳实践:控制流【读书笔记】
CUDA C 最佳实践:控制流【读书笔记】
100 0
CUDA C 最佳实践:控制流【读书笔记】
|
并行计算 C++
《并行计算的编程模型》一2.5.2 可移植平台头文件
本节书摘来华章计算机《并行计算的编程模型》一书中的第2章 ,第2.5.2节, [(美)帕万·巴拉吉(Pavan Balaji)编著;张云泉等译,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
772 0
|
并行计算
《OpenACC并行编程实战》—— 3.3 计算构件kernels
OpenACC有两个计算构件(Compute Construct):parallel和kernels,用来将循环并行化。两个构件的目标是一样的,但行为有较大的区别。初学者应优先使用简单的kernels构件,熟练以后可以使用parallel构件,众多的子语还能够精细控制并行化方案。
1625 0
《OpenACC并行编程实战》—— 2.2 OpenACC 2.5规范
本节列出OpenACC的主要构件、导语,读完本书后可以在此处快速查阅语法,不必到正文中寻找零星的介绍。初次阅读请跳过。
1540 0
|
并行计算 C语言 C++
《OpenACC并行编程实战》—— 第2章 OpenACC概览 2.1 OpenACC规范的内容
2007年出现的CUDA C/C++语言引爆了GPU通用计算热潮,但编程比较麻烦,挖掘硬件性能需要很多高超的优化技巧。为了降低编程门槛,2011年11月,Cray、PGI、CAPS和英伟达4家公司联合推出OpenACC 1.0编程标准,2012年3月PGI率先推出支持OpenACC的编译器PGI Accelerator with OpenACC。
3041 0