到目前为止,我能找到的所有答案都建议调用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变量初始化的新拷贝。您将无法从产生新线程的主线程中对其进行更改。

10-08 08:12