Parallel processing num_线程与omp_set_num_线程与omp_num_线程之间的差异

Parallel processing num_线程与omp_set_num_线程与omp_num_线程之间的差异,parallel-processing,openmp,Parallel Processing,Openmp,对于在代码的并行部分指定线程数的方法,我感到非常困惑。 我知道我可以使用: 环境变量OMP\u NUM\u THREADS 函数omp_set_num_threads(int) 中的num_线程(int)#pragma omp parallel用于num_线程(NB_OF_线程) 到目前为止,我所收集到的前两个是等价的。但是第三个呢? 如果有人能更详细地解释一下这种差异,我在互联网上找不到任何关于1/2和3之间差异的信息。想想它的范围吧。选项3(num_threads)仅为当前线程组设置线程数。

对于在代码的并行部分指定线程数的方法,我感到非常困惑。 我知道我可以使用:

  • 环境变量OMP\u NUM\u THREADS
  • 函数omp_set_num_threads(int)
  • 中的num_线程(int)#pragma omp parallel用于num_线程(NB_OF_线程)
  • 到目前为止,我所收集到的前两个是等价的。但是第三个呢?
    如果有人能更详细地解释一下这种差异,我在互联网上找不到任何关于1/2和3之间差异的信息。

    想想它的范围吧。选项3(num_threads)仅为当前线程组设置线程数。其他选项是全局/状态设置。我通常不设置线程数,而是使用默认值。当我更改线程数时,通常只在特殊情况下使用,因此我使用选项3,以便下次使用并行团队时,它返回到全局(默认)设置。请参阅下面的代码。使用选项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());
            }
        }       
    }
    
    #包括
    #包括
    int main(){
    #pragma-omp并行
    {
    #布拉格omp单曲
    {
    printf(“%d\n”,omp_get_num_threads());
    }
    }
    omp_设置_数量_线程(8);
    #pragma-omp并行
    {
    #布拉格omp单曲
    {
    printf(“%d\n”,omp_get_num_threads());
    }
    }
    #pragma omp并行num_线程(2)
    {
    #布拉格omp单曲
    {
    printf(“%d\n”,omp_get_num_threads());
    }
    }
    #pragma-omp并行
    {
    #布拉格omp单曲
    {
    printf(“%d\n”,omp_get_num_threads());
    }
    }       
    }
    
    四, 8. 2.
    8

    OMP\u NUM\u线程
    OMP\u set\u NUM\u线程()。环境变量仅用于设置nthreads var ICV(内部控制变量)的初始值,该变量控制团队中的最大线程数
    omp\u set\u num\u threads()
    可用于随时更改nthreads var的值(当然,在任何并行区域之外),并影响所有后续并行区域。因此,将值(例如,
    n
    )设置为
    OMP\u NUM\u THREADS
    相当于在遇到第一个并行区域之前调用
    OMP\u set\u NUM\u THREADS(n)

    在OpenMP网站上免费提供的中非常清楚地描述了确定并行区域中线程数的算法:

    if存在
    num\u threads
    子句

    然后将
    num_threads
    子句表达式的值设为ThreadsRequested

    否则让ThreadsRequested=第n个变量的第一个元素的值

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

    num\u threads
    子句和
    omp\u set\u num\u threads()
    覆盖
    omp\u num\u threads
    环境变量的值和第n个变量ICV的第一个元素的初始值

    翻译成人类语言,即:

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

    实际使用的线程数还受是否启用动态团队大小(dyn var ICV可通过
    OMP_dynamic
    和/或
    OMP_set_dynamic()
    设置)、线程限制是否由线程限制var施加(可通过
    OMP_thread_limit
    设置)以及嵌套并行性的影响(
    OMP\u NESTED
    /
    OMP\u set\u NESTED()
    )是否启用。

    当您说“num\u threads子句的存在将覆盖其他两个值”,范围是什么?是
    num_threads
    程序范围,还是仅用于OMP块?如果
    num_threads
    是程序范围,那么我们如何更改仅用于OMP块的线程计数?@jww,
    num_threads
    子句的范围是应用它的区域。