欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > OpenMP并行编程实例系列3 —— 线程设置

OpenMP并行编程实例系列3 —— 线程设置

2025/2/24 17:54:15 来源:https://blog.csdn.net/myw31415926/article/details/145267310  浏览:    关键词:OpenMP并行编程实例系列3 —— 线程设置

文章目录

  • OpenMP 线程设置
  • 运行环境函数
  • omp_set_dynamic 函数

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 barrieromp_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 barrierprintf("-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 程序行为的变量,比如存储线程数,线程号等信息) 是一种很好的做法,因为它的默认设置是由实现定义的,不同编译器都有各自的最优实现。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词