附录 B. OpenMP 一致性和支持

OpenMP 应用程序编程接口(API)是可移植且可伸缩的编程模型,它为用 C、C++ 和 Fortran 开发多平台的共享内存并行应用程序提供标准接口。该规范由 OpenMP 组织定义,该组织由主要的计算机硬件和软件供应商组成,其中包括 IBM。

XL C/C++ 符合“OpenMP 规范 2.0”。该编译器能识别并保持下列 OpenMP V2.0 元素的语义:

下面所描述的伪指令、库函数和环境变量可用于创建和管理并行程序,同时还保持可移植性。

要启用 OpenMP 并行处理,必须指定 -qsmp 编译器选项。

相关参考


OpenMP 伪指令

每个伪指令以 #pragma omp 开始,以减少与其它编译指示伪指令冲突的可能。

XL C/C++ 中的 OpenMP 伪指令
伪指令名称 伪指令描述
parallel parallel 伪指令定义并行区域,该区域是程序的要由多个线程并行执行的一个区域。
for for 伪指令标识一个迭代的共享工作构造,该构造指定了一个区域,在这个区域中关联循环的迭代将并行执行。for 循环的迭代分布在已经存在的线程上。
sections sections 伪指令标识非迭代的共享工作构造,该构造指定了一组构造,要将它们分配给一个队的多个线程。每一个 section 由队中的一个线程执行一次。
single single 伪指令标识一种构造,该构造指定关联的结构化块仅由队中的一个线程(不必是主线程)执行。
parallel for parallel for 伪指令是包含单个 for 伪指令的并行区域的快捷形式。其语义等同于显式指定直接后跟 for 伪指令的 parallel 伪指令。
parallel sections parallel sections 伪指令提供用于指定包含单个 sections 伪指令的并行区域的快捷形式。其语义等同于显式指定直接后跟 sections 伪指令的 parallel 伪指令。
master master 伪指令标识一种构造,该构造指定由队中主线程执行的结构化块。
critical critical 伪指令标识一种构造,该构造限制每次只能有单个线程来执行相关的结构化块。可选的 name 可以用来标识关键区域。线程在关键区域的开始处等待,直到没有其它线程具有相同名称执行关键区域为止。所有未命名的 critical 伪指令都映射到同一未指定的名称。
barrier barrier 伪指令使一个队中的所有线程同步。当遇到该伪指令时,每个线程将等待,直到所有其它线程都达到此点为止。在所有线程都遇到 barrier 后,每个线程开始以并行方式执行 barrier 伪指令之后的语句。
atomic atomic 伪指令标识特定的内存位置,该位置必须自动更新且未暴露于多个同时执行写操作的线程。
flush flush 伪指令标志了一个点,在该点编译器确保并行区域中的所有线程都具有内存中指定目标的相同视图。
ordered ordered 伪指令标识必须按顺序执行的结构化代码块。
threadprivate threadprivate 伪指令声明文件作用域、名称空间作用域或静态块作用域变量是线程私有的。

OpenMP 数据作用域属性子句

可以在伪指令中指定子句来控制在并行或工作共享构造的持续时间内变量的作用域属性。

XL C/C++ 中的 OpenMP 数据作用域属性子句
数据作用域属性子句名称 数据作用域属性子句描述
private private 子句声明列表中的变量是队中每个线程私有的。
firstprivate firstprivate 子句提供 private 子句提供的功能的超集。
lastprivate lastprivate 子句提供 private 子句提供的功能的超集。
copyprivate copyprivate 子句提供另外一种方法来替代使用共享变量将值广播到一个组这种方法。该机制使用私有变量来将值从小组的一个成员广播到另一个成员。
num_threads num_threads 子句提供了一种为并行构造请求特定数目线程的能力。
shared shared 子句在队中所有线程之间共享在列表中出现的变量。队中的所有线程访问 shared 变量的同一存储区域。
reduction reduction 子句使用指定的运算符对出现在列表中的标量变量执行归约。
default default 子句允许用户影响变量的数据作用域属性。

OpenMP 库函数

OpenMP 运行时库函数包括在头文件 <omp.h> 中。它们包括执行环境函数锁定函数,前者可以用来控制和查询并行执行环境,后者可以用来使数据访问同步。

XL C/C++ 中的 OpenMP 运行时库函数
运行时库函数名称 运行时库函数描述
omp_set_num_threads 设置要用于后续并行区域的线程数。
omp_get_num_threads 返回当前在队中执行并行区域的线程数,这些线程是从该并行区域调用的。
omp_get_max_threads 返回 omp_get_num_threads 调用可以返回的最大值。
omp_get_thread_num 返回队中正在执行函数的线程的线程号。队中的主线程是线程 0。
omp_get_num_procs 返回可以指定给程序的最大处理器数。
omp_in_parallel 如果在并行执行的并行区域的动态范围内调用它,返回非零;否则它返回 0。
omp_set_dynamic 启用或禁用可用于执行并行区域的线程数的动态调整。
omp_get_dynamic 如果启用动态线程调整,则返回非零,否则返回 0。
omp_set_nested 启用或禁用嵌套并行性。
omp_get_nested 如果启用嵌套并行性,则返回非零,而如果禁用它,则返回 0。
omp_init_lock 初始化简单锁定。
omp_destroy_lock 除去简单锁定。
omp_set_lock 等到简单锁定可用为止。
omp_unset_lock 释放简单锁定。
omp_test_lock 测试简单锁定。
omp_init_nest_lock 初始化可嵌套的锁定。
omp_destroy_nest_lock 除去可嵌套的锁定。
omp_set_nest_lock 等到可嵌套的锁定可用为止。
omp_unset_nest_lock 释放可嵌套的锁定。
omp_test_nest_lock 测试可嵌套的锁定。
omp_get_wtick 返回连续时钟信号之间的秒数。
omp_get_wtime 返回经过的挂钟时间(以秒计)。

OpenMP 环境变量

OpenMP 环境变量控制并行代码的执行。环境变量的名称必须始终为大写,尽管它们的值不区分大小写。

XL C/C++ 中的 OpenMP 环境变量
描述 语法
OMP_SCHEDULE

设置运行时调度和程序分块大小。仅适用于将调度类型设置为 runtime 的 OpenMP 伪指令。

                 .-static--+------+-------.
                 |         '-,--n-'       |
>>-OMP_SCHEDULE=-+-+-affinity-+--+------+-+--------------------><
                 | +-dynamic--+  '-,--n-' |
                 | '-guided---'           |
                 '-runtime----------------'
 
 

其中

affinity
一个仅对 C 有效的 IBM 扩展。指定循环的迭代最初分为本地分区,大小等于迭代数顶值除以线程数:CEILING(number_of_iterations ÷ number_of_threads)。每个本地分区进一步细分为程序分块,大小等于本地分区中余下的迭代数一半的顶值的块:CEILING(iterations_left_in_local_partition ÷ 2)。当线程变空闲时,它从它的本地分区中取出下一程序分块。如果本地分区中没有程序分块,则线程从另一线程的分区中取可用的程序分块。如果指定了 n,则每个本地分区细分为大小为 n 的程序分块。如果未指定 n,则缺省值是 1。

dynamic
指定 for 循环的迭代应划分为大小为 n 的一系列程序分块以及根据后面的进程处理块。对等待赋值的线程指定一组迭代,线程执行这些迭代然后等待下一次赋值。一直重复此过程,直到指定了所有程序分块为止。如果未指定 n,则缺省程序分块大小是 1。

guided
指定应将 for 循环的迭代指定给程序分块中大小不断减小的块中的线程以及根据后面的进程处理块。将完成了指定迭代程序分块的线程动态指定给另一程序分块,直到指定了所有的程序分块为止。如果未指定 n,则初始程序分块大小的缺省值是 1。

static
指定 for 循环的迭代应划分为大小为 n 的一系列程序分块以及根据后面的进程处理块。按由线程号确定的顺序将可用的线程指定给程序分块。当未指定 n 时,迭代空间划分为大小大致相等的程序分块,对每个线程指定一个块。

n
是一个正数,表示程序分块大小。
OMP_DYNAMIC

启用或禁用可用于执行并行区域的线程数的动态调整。

                .-true--.
>>-OMP_DYNAMIC=-+-false-+--------------------------------------><
 
 

其中

true
启用可用线程数的动态调整。

false
禁用可用线程数的动态调整。
OMP_NUM_THREADS

可用于执行的线程数的设置。

>>-OMP_NUM_THREADS=n-------------------------------------------><
 
 

其中

n
表示线程数。
OMP_NESTED

启用或禁用嵌套并行性。

               .-true--.
>>-OMP_NESTED=-+-false-+---------------------------------------><
 
 

其中

true
启用嵌套并行性。

false
禁用嵌套并行性。

OpenMP 实现定义的行为

在标准中未指定下列信息。标准的每个实现可以有其自己的实现定义的值。

条件编译
_OPENMP 宏定义为 199810。

调度
schedule 子句指定在队的线程之间如何划分 for 循环的迭代。可能的 OpenMP 标准值是 staticdynamicguidedruntime。此外,IBM C 添加了值 affinity 作为扩展。当没有显式定义的 schedule 子句时,XL C/C++ 的缺省调度是 static
IBM Copyright 2003