num_threads与omp_set_num_threads之间的差异与OMP_NUM_THREADS之间的差异

leo*_*nko 15 parallel-processing openmp

我对于在代码的并行部分中指定线程数的方法感到很困惑.我知道我可以用:

  1. 环境变量OMP_NUM_THREADS
  2. function omp_set_num_threads(int)
  3. num_threads(int)in #pragma omp parallel for num_threads(NB_OF_THREADS)

到目前为止我收集的前两个是等价的.但是第三个呢?有人可以提供更详细的差异说明,我无法在互联网上找到有关1/2和3之间差异的任何信息.

Hri*_*iev 26

OMP_NUM_THREADS并且omp_set_num_threads()是不等价的.环境变量仅用于设置nthreads-var ICV(内部控制变量)的初始值,该值控制团队中的最大线程数.omp_set_num_threads()可用于随时更改nthreads-var的值(当然在任何并行区域之外)并影响所有后续并行区域.因此,设置值,例如n,OMP_NUM_THREADS等于omp_set_num_threads(n)在遇到第一个并行区域之前调用.

OpenMP规范中非常清楚地描述了确定并行区域中线程数的算法,该规范可在OpenMP网站上免费获得:

如果一个num_threads条款存在

然后让 ThreadsRequested成为num_threads子句表达式的值;

否则让 ThreadsRequested = nthreads-var的第一个元素的值;

设置nthreads-var的不同方法的优先级列在规范的ICV覆盖关系部分中:

num_threads子句并omp_set_num_threads()覆盖OMP_NUM_THREADS环境变量的值和nthreads-var ICV 的第一个元素的初始值.

翻译成人类语言,即:

  • OMP_NUM_THREADS (如果存在)最初指定线程数;
  • 调用omp_set_num_threads()覆盖的值OMP_NUM_THREADS;
  • num_threads子句的存在会覆盖其他两个值.

使用的实际线程数也受动态团队规模是否已启用(dyn-var ICV可通过OMP_DYNAMIC和/或设置omp_set_dynamic()),线程限制是否由thread-limit-var(可设置的via OMP_THREAD_LIMIT)强制执行以及是否启用嵌套并行(OMP_NESTED/ omp_set_nested()).


Z b*_*son 5

认为它像范围。选项3(num_threads)仅设置当前线程组的线程数。其他选项是全局/状态设置。我通常不设置线程数,而只使用默认值。当我确实更改线程数时,通常仅在特殊情况下,所以我使用选项三,以便下次使用并行团队时,它返回到全局(默认)设置。请参见下面的代码。使用选项3后,下一组线程将返回到最后的全局设置。

#include <stdio.h>
#include <omp.h>

int main() {
    #pragma omp parallel
    {
        #pragma omp single
        {
            printf("%d\n", omp_get_num_threads());
        }
    }
    omp_set_num_threads(8);
    #pragma omp parallel
    {
        #pragma omp single
        {
            printf("%d\n", omp_get_num_threads());
        }
    }

    #pragma omp parallel num_threads(2)
    {
        #pragma omp single
        {
            printf("%d\n", omp_get_num_threads());
        }
    }

    #pragma omp parallel
    {
        #pragma omp single
        {
            printf("%d\n", omp_get_num_threads());
        }
    }       
}
Run Code Online (Sandbox Code Playgroud)

4 8 2 8