到目前为止,我能找到的所有答案都建议调用omp_set_num_threads
。尽管在大多数情况下这是一个正确的答案,但对我而言不起作用。在内部,调用omp_set_num_threads
会创建每个线程的ICV(或修改,如果当前线程已经有一个),并且线程数存储在该处。这意味着,如果有一个不同的线程启动了并行区域,那么它将看不到我们的新值。因此,调用omp_set_num_threads!=设置OMP_NUM_THREADS env变量。
有没有办法改变全局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代码时会发生的情况一无所知。
具体来说,针对您的问题:ICV num-threads
是线程专用的ICV,这意味着对omp_set_num_threads()
的调用只会影响存储在调用omp_set_num_threads()
的线程中的ICV。
因此,新的std::thread
将收到从envionment变量初始化的新拷贝。您将无法从产生新线程的主线程中对其进行更改。