OpenMP 规范定义了若干用于控制 OpenMP 程序执行的环境变量。有关详细信息,请参阅 http://openmp.org 中的 OpenMP 4.0 规范。有关在 Oracle Developer Studio 中实现 OpenMP 环境变量的信息,另请参见OpenMP 实现定义的行为。
Oracle Developer Studio 还支持Oracle Developer Studio 环境变量中汇总的不属于 OpenMP 规范的其他环境变量。
下表介绍了 Oracle Developer Studio 支持的 OpenMP 环境变量的行为及其缺省值。请注意,为环境变量指定的值不区分大小写,可以采用大写或小写形式。
|
以下其他环境变量影响 OpenMP 程序的执行,但它们不是 OpenMP 规范的一部分。请注意,为以下环境变量指定的值为不区分大小写,可以采用大写或小写形式。
为与传统程序兼容,设置 PARALLEL 环境变量的效果与设置 OMP_NUM_THREADS 的效果相同。
如果同时设置 PARALLEL 和 OMP_NUM_THREADS,则必须将它们设置为相同的值。
OpenMP 运行时库能够发出有关许多常见 OpenMP 违规的警告,例如区域嵌套错误、显式屏障位置错误、死锁、环境变量的设置无效等等。
环境变量 SUNW_MP_WARN 控制 OpenMP 运行时库发出的警告消息。如果将 SUNW_MP_WARN 设置为 TRUE,运行时库会向 stderr 发出警告消息。如果将该环境变量设置为 FALSE,运行时库将不发出任何警告消息。缺省值为 FALSE。
示例:
% setenv SUNW_MP_WARN TRUE
如果程序注册一个回调函数以接受警告消息,则运行时库也将发出警告消息。程序可通过调用以下函数来注册回调函数:
int sunw_mp_register_warn (void (*func)(void *));
回调函数的地址作为参数传递给 sunw_mp_register_warn()。sunw_mp_register_warn() 在成功注册回调函数后返回 0,失败后返回 1。
如果程序已注册了回调函数,运行时库将调用该注册的函数,并将一个指针传递给包含警告消息的本地化字符串。从回调函数返回后,指向的内存将不再有效。
控制 OpenMP 程序中正在等待工作(空闲)或者正在屏障处等待的线程的行为。可以将该值设置为以下值之一:SPIN、SLEEP、SLEEP(time s)、SLEEP(time ms)、SLEEP(time mc),其中 time 是一个指定时间量的整数,s、ms 和 mc 是可选后缀,指定时间单位(分别为秒、毫秒和微秒)。如果未指定时间单位,则采用秒作为时间单位。
SPIN 指定线程在等待工作(空闲)或在屏障处等待时应旋转。不带时间参数的 SLEEP 指定等待线程应立即休眠。带时间参数的 SLEEP 指定线程进入休眠状态前应旋转等待的时间量。
缺省行为是经过一段时间的旋转等待后进入休眠状态。SLEEP、SLEEP(0)、SLEEP(0s)、SLEEP(0ms) 和 SLEEP(0mc) 都是等效的。
如果同时设置 SUNW_MP_THR_IDLE 和 OMP_WAIT_POLICY,则将忽略 OMP_WAIT_POLICY。
示例:
% setenv SUNW_MP_THR_IDLE SPIN % setenv SUNW_MP_THR_IDLE SLEEP
以下项等效:
% setenv SUNW_MP_THR_IDLE SLEEP(5) % setenv SUNW_MP_THR_IDLE SLEEP(5s) % setenv SUNW_MP_THR_IDLE SLEEP(5000ms) % setenv SUNW_MP_THR_IDLE SLEEP(5000000mc)
SUNW_MP_PROCBIND 环境变量可用于将 OpenMP 线程绑定到正在运行的系统上的硬件线程。虽然可以通过处理器绑定来增强性能,但是如果将多个线程绑定到同一硬件线程,则会导致性能下降。无法同时设置 SUNW_MP_PROCBIND 和 OMP_PROC_BIND。如果未设置 SUNW_MP_PROCBIND,则缺省值为 FALSE。有关更多信息,请参见处理器绑定(线程关联性)。
指定 OpenMP 辅助线程池的最大大小。OpenMP 辅助线程是 OpenMP 运行时库创建的用于在并行区域上运行的那些线程。辅助线程池不包含初始线程(或主线程)和由用户程序显式创建的任何线程。如果将此环境变量设置为零,则 OpenMP 辅助线程池将为空,并且将由初始线程(或主线程)执行所有并行区域。如果未设置,则使用缺省值 1023。有关更多信息,请参见控制嵌套并行操作。
请注意,SUNW_MP_MAX_POOL_THREADS 指定用于程序的非用户 OpenMP 线程的最大数量,而 OMP_THREAD_LIMIT 指定用于程序的用户和非用户 OpenMP 线程的最大数量。如果同时设置 SUNW_MP_MAX_POOL_THREADS 和 OMP_THREAD_LIMIT,则必须将它们设置为相同的值。OMP_THREAD_LIMIT 的值必须比 SUNW_MP_MAX_POOL_THREADS 的值大 1。
设置嵌套活动并行区域的最大数量。如果由包含多个线程的组执行并行区域,则该并行区域处于活动状态。如果未设置 SUNW_MP_MAX_NESTED_LEVELS,则缺省值为 4。有关更多信息,请参见控制嵌套并行操作。
设置每个 OpenMP 辅助线程的堆栈大小。该环境变量接受带可选后缀 B、K、M 或 G(分别表示字节、千字节、兆字节或千兆字节)的数值。如果未指定后缀,则使用缺省单位千字节。
如果未设置,则对于 32 位应用程序,缺省 OpenMP 辅助线程堆栈大小为 4 MB;对于 64 位应用程序,缺省值为 8 MB。
示例:
% setenv STACKSIZE 8192 <- sets the OpenMP helper thread stack size to 8 Megabytes % setenv STACKSIZE 16M <- sets the OpenMP helper thread stack size to 16 Megabytes
请注意,如果同时设置 STACKSIZE 和 OMP_STACKSIZE,则必须将它们设置为相同的值。
设置加权因子,该因子用于确定使用 guided 调度的循环中的块大小。该值应为正浮点数,并且应用于程序中所有使用 guided 调度的循环。如果未设置,则缺省加权因子为 2.0。
当使用 for/do 指令指定 schedule(guided, chunk_size) 子句时,会在线程请求时将循环迭代以块形式分配给线程,块大小一直减小到 chunk_size,最后一个块的大小可能小于该值。线程执行一个迭代块,然后请求另一个块,直到没有块可以分配为止。对于 chunk_size 为 1 的情况,每个块的大小按照未分配的迭代数除以线程数的值成比例分配,一直减小到 1。对于 chunk_size 为 k(这里 k 大于 1)的情况,每个块的大小按照相同方式进行确定但遵循如下限制:块包含的迭代不少于 k 次(最后一个块除外)。未指定 chunk_size 时,该值缺省为 1。
OpenMP 运行时库 libmtsk.so 使用以下公式来计算使用 guided 调度的循环的块大小:
chunk_size = num-unassigned-iters / (guided-weight * num-threads)
num-unassigned-iters 是循环中尚未分配给任何线程的迭代数。
guided-weight 是 SUNW_MP_THR_GUIDED_WEIGHT 环境变量指定的加权因子(如果未设置环境变量,则为 2.0)。
num-threads 是用于执行循环的线程数。
举例来说,假定有一个使用 guided 调度的 100 次迭代循环。如果 num-threads = 4,加权因子 = 1.0,那么块大小将是:
25、18、14、10、8、6、4、3、3、2、1...
另一方面,如果 num-threads= 4,加权因子 = 2.0,那么块大小将是:
12、11、9、8、7、6、5、5、4、4、3...
允许更精确地控制程序中等待工作(空闲)、在屏障处等待或等待任务完成的 OpenMP 线程的行为。在这些等待类型中,每一类型的行为都有三种可能:旋转片刻、让出处理器片刻或休眠直至被唤醒。
语法(使用 csh 显示)如下:
% setenv SUNW_MP_WAIT_POLICY "IDLE=val:BARRIER=val:TASKWAIT=val"
IDLE、BARRIER 和 TASKWAIT 是指定所控制的等待类型的可选关键字。IDLE 指等待运行。BARRIER 指在显式或隐式屏障处等待。TASKWAIT 指在 taskwait 区域等待。上述每个关键字都后跟一个 val 设置,使用关键字 SPIN、YIELD 或 SLEEP 来描述等待行为。
SPIN(time) 指定等待线程在让出处理器之前应旋转多长时间。time 可以是秒、毫秒或微秒(分别用 s、ms 或 mc 表示)。如果不指定 time 单位,则使用秒。如果 SPIN 不带 time 参数,表示线程在等待时应持续旋转。
YIELD(number) 指定线程在休眠之前应让出处理器的次数。每次让出处理器后,线程会在操作系统调度其运行时再次运行。如果 YIELD 不带 number 参数,表示线程在等待时应持续让出。
SLEEP 指定等待线程应立即转入休眠。
请注意,可以按任意顺序指定特定等待类型的 SPIN、SLEEP 和 YIELD 设置。各个设置必须使用逗号分隔。"SPIN(0),YIELD(0)" 与 "YIELD(0),SPIN(0)" 相同,等效于 SLEEP 或立即休眠。在处理 IDLE、BARRIER 和 TASKWAIT 的设置时,采用左侧优先规则。“左侧优先”规则表示,如果为相同等待类型指定不同的值,那么最左侧的值是要应用的值。在以下示例中,为 IDLE 指定了两个值。第一个是 SPIN,第二个是 SLEEP。因为 SPIN 首先出现(它在字符串的最左侧),所以这是 OpenMP 运行时库将要应用的值。
% setenv SUNW_MP_WAIT_POLICY "IDLE=SPIN:IDLE=SLEEP"
如果同时设置 SUNW_MP_WAIT_POLICY 和 OMP_WAIT_POLICY,则将忽略 OMP_WAIT_POLICY。
示例 1:
% setenv SUNW_MP_WAIT_POLICY “BARRIER=SPIN”
在屏障等待的线程将一直旋转,直到组中的所有线程都到达该屏障。
示例 2:
% setenv SUNW_MP_WAIT_POLICY “IDLE=SPIN(10ms),YIELD(5)”
等待工作(空闲)的线程旋转 10 毫秒,然后让出处理器 5 次,再转入休眠。
示例 3:
% setenv SUNW_MP_WAIT_POLICY “IDLE=SPIN(2s),YIELD(2):BARRIER=SLEEP:TASKWAIT=YIELD(10)”
等待工作(空闲)的线程旋转 2 秒,然后让出处理器 2 次,再转入休眠;在屏障处等待的线程立即转入休眠;在 taskwait 处等待的线程让出处理器 10 次,再转入休眠。