c++ - 从代码中覆盖 OMP_NUM_THREADS - 真的
问题描述
到目前为止,我能找到的所有答案都建议致电omp_set_num_threads
. 虽然对于大多数情况来说这是一个正确的答案,但它对我不起作用。在内部,调用omp_set_num_threads
会导致创建每个线程 ICV(或修改,如果当前线程已经有一个),并且线程数存储在那里。这意味着如果有一个不同的线程启动一个并行区域,它将看不到我们的新值。所以调用 omp_set_num_threads != 设置 OMP_NUM_THREADS 环境变量。
有没有办法改变全球 ICV?
旁注 - 我为什么要这样做:我正在使用一个库为我生成一个工作线程,所以我并没有真正控制它的生命周期。
最简单的重现示例:
export OMP_NUM_THREADS=3
#include <omp.h>
#include <iostream>
#include <thread>
void job() {
#pragma omp parallel
{
if (omp_get_thread_num() == 0) {
std::cout << "Num threads:" << omp_get_num_threads() << std::endl;
}
};
}
int main () {
omp_set_num_threads(2);
#pragma omp parallel
{
if (omp_get_thread_num() == 0) {
std::cout << "Num threads:" << omp_get_num_threads() << std::endl;
}
};
std::thread t(job);
t.join();
}
这产生
Num threads:2
Num threads:3
解决方案
您试图实现的问题超出了 OpenMP 的规范。OpenMP 假定它是应用程序进程中唯一的编程模型,因此它确实知道当您创建一个也执行 OpenMP 代码的新线程时会发生什么。
具体来说,对于您的问题:ICVnum-threads
是线程私有的 ICV,这意味着对 的调用omp_set_num_threads()
仅影响存储在调用omp_set_num_threads()
.
因此,新的std::thread
将收到一个从环境变量初始化的新副本。您将无法从产生新线程的主线程中更改它。
推荐阅读
- swift - SwiftUI 通用链接不适用于 NFC
- amazon-web-services - 在负载均衡器后面无法访问我的 Ec2 实例
- javascript - jquery.min.js:2 Uncaught TypeError: Cannot read property 'replace' of undefined (javascript)(laravel)
- php - 用 php 发布推文的问题
- c++ - 矢量显示迭代器提前结束
- java - 如何设置缓存的过期时间?
- visual-studio-code - 在 VSCode 中下载 Vim 扩展的脚本
- java - How to access hashmap object with class object as key
- java - 如何通过反射api从java将值注入groovy脚本中的字段?
- python - python tkinter条目变量未定义