马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
OpenMP 线程设置
OpenMP 可以在程序中设置线程数,常用的有 3 种方式:
- 使用环境变量 OMP_NUM_THREADS 设置线程数;
- 调用 OpenMP 的环境函数 omp_set_num_threads 设置线程数;
- 直接在 #pragma omp 语句中使用 num_threads 关键字设置线程数。
别的,还支持在多个嵌套级别上控制线程数(不同嵌套中线程可以不同)。以下的实例展示如何使用环境变量 OMP_NUM_THREADS 在多个嵌套级别上控制线程数目,为了理顺逻辑,我添加了一些打印信息。
- // desc: Controlling the Number of Threads on Multiple Nesting Levels
- // file: omp_nthrs_nesting.cpp
- #include <cstdio>
- #include <omp.h>
- int main(int argc, char const *argv[])
- {
- omp_set_nested(1); // 设置允许嵌套并行
- omp_set_dynamic(0); // 静止动态改变线程数
- #pragma omp parallel
- {
- int tid1 = omp_get_thread_num();
- printf("-1: %d\n", tid1);
- #pragma omp parallel
- { // 嵌套并行
- int tid2 = omp_get_thread_num();
- printf("-2: %d - %d\n", tid1, tid2);
- #pragma omp single
- {
- printf("inner1: num threads %d\n", omp_get_num_threads());
- }
- }
- #pragma omp barrier
- omp_set_nested(0);
- #pragma omp parallel
- {
- int tid2 = omp_get_thread_num();
- printf("-3: %d - %d\n", tid1, tid2);
- #pragma omp single
- {
- printf("inner2: num threads %d\n", omp_get_num_threads());
- }
- }
- #pragma omp barrier
- printf("-4: %d\n", tid1);
- #pragma omp single
- {
- printf("outter: num threads %d\n", omp_get_num_threads());
- }
- }
- return 0;
- }
复制代码 程序中一些 omp 子句的分析:
- #pragma omp single
指定并行域中的串行任务,创建仅由一个线程实行的任务,先到先实行,其他线程期待实在行结束后再一起实行后面的任务。
- #pragma omp barrier
期待同步:用在并行域内,全部线程实行到 barrier 都要停下期待,直到全部线程都实行到 barrier,然后再继续往下实行
以下是线程数为 2 和 3 的输出结果
- $ export OMP_NUM_THREADS=2 # 通过环境变量,设置线程数为2
- $ ./omp_nthrs_nesting
- -1: 0 # 外层的线程
- -1: 1
- -2: 0 - 0 # 嵌套的线程
- inner1: num threads 2 # single输出
- -2: 0 - 1
- -2: 1 - 0
- inner1: num threads 2 # single输出
- -2: 1 - 1
- -3: 0 - 0 # 外层线程,禁止嵌套
- inner2: num threads 1 # single输出
- -3: 1 - 0
- inner2: num threads 1 # single输出
- -4: 0 # 外层线程
- outter: num threads 2 # single输出
- -4: 1
- $ export OMP_NUM_THREADS=3
- $ ./omp_nthrs_nesting
- -1: 0
- -1: 2
- -1: 1
- -2: 0 - 0
- inner1: num threads 3
- -2: 0 - 2
- -2: 0 - 1
- -2: 2 - 1
- -2: 2 - 0
- -2: 2 - 2
- -2: 1 - 0
- inner1: num threads 3
- -2: 1 - 1
- -2: 1 - 2
- inner1: num threads 3
- -3: 0 - 0
- inner2: num threads 1
- -3: 2 - 0
- inner2: num threads 1
- -3: 1 - 0
- inner2: num threads 1
- -4: 0
- outter: num threads 3
- -4: 1
- -4: 2
复制代码 运行环境函数
运行环境函数(Execution Environment Routines)是用于设置和获取 OpenMP 运行属性的函数,常用函数如下:
函数 分析 omp_set_num_threads(int)设置并行域中的线程个数(用在串行域中)omp_get_num_threads()返回当前并行域中的线程个数omp_get_max_threads()返回并行域中缺省可用的最大线程个数omp_get_thread_num()返回当火线程的线程号,0号为主线程omp_get_num_procs()返回系统中处理器的个数omp_in_parallel()判断是否在并行域中omp_set_dynamic(int)启用或关闭线程数目动态改变功能(用在串行域中)omp_get_dynamic()判断系统是否支持动态改变线程数目omp_set_nested(int)启用或关闭并行域嵌套功能(缺省为关闭)omp_get_nested()判断系统是否支持并行域的嵌套 omp_set_dynamic 函数
函数 omp_set_dynamic 是启用或关闭线程数目动态改变功能,须要在串行域中调用。它可以使 num_threads 子句的设置失效。实比方下:
- // desc: Interaction Between the num_threads Clause and omp_set_dynamic
- // file: omp_nthrs_dynamic.1.cpp
- #include <cstdio>
- #include <omp.h>
- int main(int argc, char const *argv[])
- {
- omp_set_dynamic(1);
- // omp_set_dynamic(0);
- #pragma omp parallel num_threads(10)
- {
- int tid1 = omp_get_thread_num();
- printf("tid: %d\n", tid1);
- }
- return 0;
- }
复制代码 第 9 行调用 omp_set_dynamic(1) 支持动态改变线程数,输出如下:
- $ export OMP_NUM_THREADS=3 # 默认为3线程
- $ ./omp_nthrs_dynamic.1 # 运行时设为10个线程
- tid: 3
- tid: 2
- tid: 0
- tid: 6
- tid: 4
- tid: 5
- tid: 1
- tid: 7
- tid: 9
- tid: 8
复制代码 若屏蔽第 9 行代码,放开第 10 行 omp_set_dynamic(0) ,不支持动态改变线程数,则输出如下:
- $ ./omp_nthrs_dynamic.1
- tid: 0
- tid: 2
- tid: 1
复制代码 通过调用 omp_set_dynamic 函数显式设置 ICV( Internal Control Variables 内置控制变量,用于控制 OpenMP 程序举动的变量,比如存储线程数,线程号等信息) 是一种很好的做法,因为它的默认设置是由实现定义的,不同编译器都有各自的最优实现。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |