OpenMP omp_get_num_threads() VS omp_get_max_threads()

Sea*_*ean 3 c++ openmp

我不明白 omp_get_num_threads() 和 omp_get_max_threads() 之间的区别。我复制了演示代码如下。

    omp_set_nested(1);
    omp_set_max_active_levels(10);
    omp_set_dynamic(0);
    omp_set_num_threads(2);
    #pragma omp parallel 
    {
        omp_set_num_threads(3);

        #pragma omp parallel
        {
            omp_set_num_threads(4);
            #pragma omp single
            {
                std::cout << omp_get_max_active_levels() << " " << omp_get_num_threads() << " " 
                << omp_get_max_threads() << std::endl;
            }
        }

        #pragma omp barrier
        #pragma omp single 
        {
            std::cout << omp_get_max_active_levels() << " " << omp_get_num_threads() << " " 
                << omp_get_max_threads() << std::endl;
        }
    }
Run Code Online (Sandbox Code Playgroud)

然后我得到以下输出。

10 3 4
10 3 4
10 3 4
10 3 3
Run Code Online (Sandbox Code Playgroud)

我查了官方文档,但还是很困惑。

648*_*ade 7

来自文档:

omp_get_num_threads

该例程返回执行例程区域绑定的区域的omp_get_num_threads组中的线程数。parallel如果从程序的顺序部分调用,则此例程返回 1。

omp_get_max_threads

返回的值是当前任务的nthreads-varomp_get_max_threads ICV的第一个元素的值。如果从此例程执行返回后遇到没有子句的并行区域,则该值也是可用于形成新团队的线程数的上限。num_threads

下图说明了线程的流程。您的输出可能不正确,我无法使用 clang+libomp 或 gcc+libGOMP 重现它。

在此输入图像描述

如果未同时指定线程数,则始终返回新构造可以创建的线程数omp_get_max_threads。parallel当您在内部并行区域设置 4 时omp_set_num_threads,可以创建的新不同线程的最大数量为 4,但该区域中正在使用 3 个线程。对于外部并行区域,最大值为 3,并且正在使用 2 个。

omp_set_num_threads在串行代码中,在任何编译指示中,线程数都是 1,但如果您没有通过或OMP_NUM_THREADS环境变量更改它,则最大值是系统的默认值(通常是核心数)