omp_get_max_threads()在并行区域中返回1,但它应为8

时间:2017-08-02 22:39:05

标签: c++ multithreading openmp

我在Linux上编译一个使用OpenMP的复杂C ++项目,使用CMake和GCC 7编译。 我在这个特定项目中遇到的奇怪问题是OpenMP显然正在工作,但它认为只支持1个线程,当它应该是8.但是,如果我手动指定线程数,它确实加速代码。

logOut << "In parallel? " << omp_in_parallel() << std::endl;
logOut << "Num threads = " << omp_get_num_threads() << std::endl;
logOut << "Max threads = " << omp_get_max_threads() << std::endl;

logOut << "Entering my parallel region: " << std::endl;

//without num_threads(5), only 1 thread is created
#pragma omp parallel num_threads(5) 
  {          
      #pragma omp single nowait
      {
          logOut << "In parallel? " << omp_in_parallel() << std::endl;
          logOut << "Num threads = " << omp_get_num_threads() << std::endl;
          logOut << "Max threads = " << omp_get_max_threads() << std::endl;
      }
  }

输出:

[openmp_test] In parallel? 0
[openmp_test] Num threads = 1
[openmp_test] Max threads = 1
[openmp_test] Entering my parallel region: 
[openmp_test] In parallel? 1
[openmp_test] Num threads = 5
[openmp_test] Max threads = 1

使它更奇怪的是,一个简单的测试OpenMP程序直接正确地将并行区域内外的最大线程数报告为8。 我一直在梳理所有的CMake文件,试图找出这个项目为什么表现不同的任何指标,但到目前为止我还没有发现任何事情。在我的任何项目文件中都没有提到omp_set_num_threads,我可以确认没有声明OMP_NUM_THREADS。此外,当我使用MSVC在Windows上编译相同的项目时,这个问题从未发生过。

任何想法可能是什么问题?

(编辑:我已经扩展了代码示例以显示它不是嵌套的并行块)

CPU:Intel(R)Core(TM)i7-6700K

操作系统:Manjaro Linux 17.0.2

编译:GCC 7.1.1 20170630

_OPENMP = 201511(我猜这意味着OpenMP 4.5)

2 个答案:

答案 0 :(得分:1)

您的程序的行为与之前调用的omp_set_num_threads(1)完全相同。

考虑这个片段:

#include <iostream>
#include <string>
#include <vector>
#include "omp.h"
int main() {

omp_set_num_threads(1);

std::cout << "before parallel section: " << std::endl;
std::cout << "Num threads = " << omp_get_num_threads() << std::endl;
std::cout << "Max threads = " << omp_get_max_threads() << std::endl;

//without num_threads(5), only 1 thread is created
#pragma omp parallel num_threads(5) 
  {          
      #pragma omp single
      {
          std::cout << "inside parallel section: " << std::endl;
          std::cout << "Num threads = " << omp_get_num_threads() << std::endl;
          std::cout << "Max threads = " << omp_get_max_threads() << std::endl;
      }
  }

  return 0;
}

输出

before parallel section: 
Num threads = 1    
Max threads = 1
inside parallel section:  
Num threads = 5
Max threads = 1

当我通过将线程数设置为4而不是1(机器上的8)来运行它时,输出符合预期:

before parallel section: 
Num threads = 1
Max threads = 4
inside parallel section: 
Num threads = 5
Max threads = 4

您是否尝试在代码开头调用omp_set_num_threads(8)?或者您是否在程序之前将线程数设置为1(例如,在调用此函数的函数内部?)?

另一个解释可能是openMP API没有必要拥有多个线程,因为在并行部分中只实现了一个部分。在这种情况下,尝试添加一些可以由多个线程执行的代码,以便在单个部分之外但在并行部分内部和线程数内更快地运行(即递增大型整数数组的所有值或调用omp_get_thread_num())应该是不同的。调用omp_set_num_threads仅设置使用的线程数的上限。

答案 1 :(得分:1)

您在并行区域内看到的值似乎是正确的(假设OMP_NESTED不正确)。 omp_get_max_threads()返回当前线程并行时可能获得的最大线程数。由于您已经在并行区域内(并且我们假设已禁用嵌套并行性),因此它将是一个。

  

3.2.3 omp_get_max_threads

     

概要
  omp_get_max_threads例程返回可以使用的线程数的上限   如果没有num_threads的并行构造,则形成一个新团队   执行从此例程返回后遇到子句。

但这并不能解释为什么你会看到并行区域之外的值。 (但它确实回答了标题中的问题,答案是&#34;一个是正确答案&#34;)。