OpenMP 預設只會平行化第一階層 directives ,當被平行化的 thread 再呼叫 OpenMP 時會自動被忽略,但是我們可以強制展開巢狀階層的 directives ,對於 function 呼叫產生新的 thread 也同樣有效
兩種解法,一是在程式碼中插入omp_set_nested(1),另外就是從環境變數著手,如下兩種都可以
第一種方法是在程式碼中呼叫 omp_set_nested ,使用需要 include omp.h
omp_set_nested(1);
第二種方法則是設定環境變數,注意環境變數的優先權比 omp_set_nested 低,所以會被覆蓋
set OMP_NESTED=TRUE
一個完整的 nested openmp parallel for 範例,這邊使用 omp_set_nested ,第一次呼叫 fun() 時會同時產生 4 個 thread,第二次呼叫 fun() 時由於沒有 nested parallelization 則是 2 個 thread
#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 是同時被平行化的,反之則是無平行化循序執行
0 1 0 0 0 0 1 1 0 1 0 0 0 0 1014 1 0 1014 0 1 2028 1 1 2028
