使用 omp_set_num_threads 后,我可以让 OpenMP 恢复到理想的线程数吗?

Posted

技术标签:

【中文标题】使用 omp_set_num_threads 后,我可以让 OpenMP 恢复到理想的线程数吗?【英文标题】:Can I make OpenMP to revert to ideal # of threads after using omp_set_num_threads? 【发布时间】:2019-07-10 16:45:05 【问题描述】:

有没有办法让 OpenMP 将线程数(在下次使用时)恢复为默认值应用程序已经调用了omp_set_num_threads()有一个具体的数字?

例如,是否有我提供给omp_set_num_threads 的特殊代码(例如 0 或 -1)?

或者我应该尝试做类似omp_set_num_threads(omp_get_max_threads()) 的事情吗?

我假设默认数字是 OpenMP 的实现认为“最佳”的任何值。但我不知道,如果有的话,默认是什么,甚至应该是什么。我所知道的是,我有一个应用程序调用 omp_set_num_threads(4) 来处理一个我不能编辑的特定 OpenMP 块(现在)。但我想防止该设置影响我代码中的其他 OpenMP 块。

【问题讨论】:

您使用的是哪个编译器和 OpenMP 版本? Visual Studio 2019 以及 Ubuntu 上最新的 GCC 版本。遗憾的是,我还必须在 Visual Studio 2015 下构建代码,但在这种情况下,我愿意尝试另一种特定于 Windows 的方法。展望未来,我将能够坚持使用 VS2019 及更高版本 如果构造中存在num_threads 子句,则不会使用omp_set_num_threads 设置的值。也许你可以在你控制的代码中使用它?或者更改“一个特定的 OpenMP 块”以使用它而不是 omp_set_num_threads 不幸的是,一个特定的块正在使用用户可以更改的可配置参数。所以我不能用 num_threads 子句将数字写入代码 【参考方案1】:

我以前遇到过这个问题。 (免责声明:我使用的是 MSVC,它目前只实现了 OpenMP 2.0 标准)。据我所知,OpenMP 2.0 standard 中没有任何内容可以让您找出这个默认值。 omp_get_max_threads() 不需要返回它(所有后续强调我的):

omp_get_max_threads 函数返回一个整数,如果并行区域没有 num_threads 子句,则该整数保证至少与用于组成团队的线程数一样大将在代码中的那个点遇到。

换句话说,它可能返回一个大于当前设置(或默认)值的数字。

omp_set_num_threads 也没有特殊值:

omp_set_num_threads 函数设置用于未指定num_threads 子句的后续并行区域的默认线程数。 [...] 参数num_threads 的值必须是正整数

如果你弄错了,这取决于实现会发生什么:

如果在禁用线程数动态调整时遇到并行区域,并且为并行区域请求的线程数超过运行时系统可以提供的数量,则程序的行为是实现定义的。例如,一个实现可能会中断程序的执行,或者它可能会串行化并行区域。

您可能会在您的 OpenMP 实施文档中找到更准确(并且更少令人不安)的信息。但是,对于 MSVC,该文档只是 OpenMP 2.0 标准的逐字副本...


由于您从事这种方式修改线程数的业务,因此我想先提醒您注意MSVC中omp_set_dynamicomp_get_num_threads的交互:Why does omp_set_dynamic(1) never adjust the number of threads (in Visual C++)?

【讨论】:

我没有DV,可能是因为2.0版本太旧了? OpenMP 最高为 5.0 版。 @1201ProgramAlarm 我同意(并将添加免责声明),但最新的 MSVC 仍然只实现 2.0 标准,而且我没有在其他编译器上使用 OpenMP 的经验。 是的,请不要引用一个已有近 20 年历史的规范,因为它已经进行了六次修订(三个主要修订)。该帖子还遗漏了关键点,即在最新的 OpenMP 中,线程数的规范可以是类似列表的结构,无法从用户代码中查询所有可能在运行时执行的嵌套级别。因此,查询当前级别的线程数的唯一方法是打开一个并行区域,询问线程数并返回该数。需要注意的是,这个数字可能仍然是错误的,因为它可能会根据omp_set_dynamic而改变 @MichaelKlemm 这个有 20 年历史的规范是三大 C++ 编译器之一支持的最新规范。我也希望那是不同的,但到目前为止,我的答案正是我几个月前一直在寻找的,并且我认为提问者想知道他们现在是否正在使用 MSVC。即使他们不是,它也可能会帮助其他人(除非 MSVC 明天更新他们的 OMP 支持)。 @Joe MSVC supports OpenMP 2.0,并通过 /openmp:experimental 选项启用 SIMD 功能。

以上是关于使用 omp_set_num_threads 后,我可以让 OpenMP 恢复到理想的线程数吗?的主要内容,如果未能解决你的问题,请参考以下文章

包内的 Rcpp omp_set_num_threads

从代码中覆盖 OMP_NUM_THREADS - 真的

OpenMP 不会利用所有内核?

是否可以使用 openmp 对数组进行缩减?

影响 OpenMP 并行效率的方面

openmp怎么用函数配置线程数