OpenMP 預設只會平行化第一階層 directives ,當被平行化的 thread 再呼叫 OpenMP 時會自動被忽略,但是我們可以強制展開巢狀階層的 directives ,對於 function 呼叫產生新的 thread 也同樣有效
兩種解法,一是在程式碼中插入omp_set_nested(1),另外就是從環境變數著手,如下兩種都可以
第一種方法是在程式碼中呼叫 omp_set_nested ,使用需要 include omp.h
1 |
omp_set_nested(1); |
第二種方法則是設定環境變數,注意環境變數的優先權比 omp_set_nested 低,所以會被覆蓋
1 |
set OMP_NESTED=TRUE |
一個完整的 nested openmp parallel for 範例,這邊使用 omp_set_nested ,第一次呼叫 fun() 時會同時產生 4 個 thread,第二次呼叫 fun() 時由於沒有 nested parallelization 則是 2 個 thread
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#include <omp.h> #include <stdio.h> #include <time.h> #include <windows.h> void fun() { #pragma omp parallel for for (int i = 0; i < 2; ++i) { #pragma omp parallel for for (int j = 0; j < 2; ++j) { printf("%d %d %d\n", i, j, (int)clock()); Sleep(1000); } } } int main() { omp_set_nested(1); fun(); omp_set_nested(0); fun(); return 0; } |
執行結果如下,當 omp_set_nested 設為 1 時,第二層 loop 是同時被平行化的,反之則是無平行化循序執行
1 2 3 4 5 6 7 8 |
0 1 0 0 0 0 1 1 0 1 0 0 0 0 1014 1 0 1014 0 1 2028 1 1 2028 |