2017-07-24 419 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接口無關,當然,如果強制增加線程數量,除了已經存在的線程外,還必須創建新的線程。