从代码中覆盖 OMP_NUM_THREADS - 真正的 [英] Overriding OMP_NUM_THREADS from code - for real

查看:45
本文介绍了从代码中覆盖 OMP_NUM_THREADS - 真正的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

到目前为止我能找到的所有答案都建议调用 omp_set_num_threads.虽然在大多数情况下这是一个正确的答案,但它对我不起作用.在内部,调用 omp_set_num_threads 会导致创建每线程 ICV(或修改,如果当前线程已经有一个),并且线程数存储在那里.这意味着如果有一个不同的线程启动了一个并行区域,它将看不到我们的新值.所以调用 omp_set_num_threads != 设置 OMP_NUM_THREADS 环境变量.

All the answers I was able to find so far suggest calling omp_set_num_threads. While it's a proper answer for most cases, it doesn't work for me. Internally, calling omp_set_num_threads causes a creation of per-thread ICV (or modification, if current thread already has one), and the number of threads is stored there. This means that if there is a different thread, that starts a parallel region, it won't see our new value. So calling omp_set_num_threads != setting OMP_NUM_THREADS env variable.

有没有办法改变全球 ICV?

Is there a way to change global ICV?

旁注 - 我为什么要这样做:我正在使用一个库为我生成一个工作线程,所以我并没有真正控制它的生命周期.

Side note - why would I want to to this: I'm working with a library spawns a worker thread for me, so I don't really control it's life-cycle.

最简单的重现示例:

导出 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 代码的新线程时会发生什么.

The problem with what you're trying to achieve is outside of OpenMP's specification. OpenMP assumes that it's the only programming model in the application process and thus it does know anything about what happens when you create a new thread that also executes OpenMP code.

具体来说,对于您的问题:ICV num-threads 是线程私有的 ICV,这意味着对 omp_set_num_threads() 的调用只会影响存储的 ICV在调用 omp_set_num_threads() 的线程中.

Specifically, for your problem: the ICV num-threads is a thread-private ICV, that means, that a call to omp_set_num_threads() only affects the ICV stored in the thread that calls omp_set_num_threads().

因此,新的 std::thread 将收到一个从环境变量初始化的新副本.您将无法从生成新线程的主线程更改它.

So, the new std::thread will receive a new copy that initialized from the envionment variable. You won't be able to change it from the master thread that spawned the new thread.

这篇关于从代码中覆盖 OMP_NUM_THREADS - 真正的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆