2017-07-24 204 views
1

在下面的代码中,OpenMP运行时将重新创建线程,还是重新使用先前创建的线程 - 即使用线程池?OpenMP线程创建

有些同事认为它会重新创建线程,因为“#parallel”子句嵌套在for中;我怀疑这一点,并对GDB进行了一些测试,结果表明这不是事实。线程实际上被重用。

#include <cstdio> 
#include <omp.h> 
#include <unistd.h> 

void fun1() { 
    for (int j=1; j<=5; j++) { 
     #pragma omp parallel for 
     for (int i=1; i<=5; i++) { 
      printf("Hahaha %d -> %d\n", omp_get_thread_num(), i); 
     } 
    } 
} 

void fun2() { 
    for (int j=1; j<=5; j++) { 
     #pragma omp parallel for 
     for (int i=1; i<=5; i++) { 
      printf("Hahaha %d -> %d\n", omp_get_thread_num(), i); 
     } 
    } 
} 

int main() { 

    fun1(); 

    sleep(1); 

    fun2(); 

    return 0; 
} 
+0

我会认为它会重用相同的线程,因为它没有失去范围,直到它退出最外层的'for'。如果它没有丢失范围,那么我会认为没有连接,如果没有连接,那么它会继续使用相同的线程。 – Matthew

+0

我正在观察的是,即使跨越不同的函数调用 - 即通过调用fun1和fun2,线程也被重用。 – JohnTortugo

+0

从我可以告诉它与OMP设置线程团队有关,我会假设在整个项目生命周期中重新使用该团队。这将导致使用相同的线程 – Matthew

回答

0

OpenMP标准描述了实现所需的语义,而不是如何实现这些语义,因此标准没有提到使用线程池。

然而

  1. 标准确实有关于线程本地存储它意味着一个线程池是实现所需的语义最简单的方法的持续性规则。
  2. 编写OpenMP实现的人不是傻瓜,所以使用尽可能快的实现(因此使用线程池)。

因此,虽然您不能保证使用线程池,但您可以合理地预期它是。

关于此声明的验证,请查看开源OpenMP运行时的代码,例如LLVM(这也是英特尔编译器使用的运行时)以及GCC的gomp

p.s.线程池的使用与使用任何特定的OpenMP接口无关,当然,如果强制增加线程数量,除了已经存在的线程外,还必须创建新的线程。