OpenMP nested parallelization

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