我想寫一個函數,它使用openMP並行性,但應該工作,無論是否在並行區域內調用。所以我用了if
子句來抑制並行,但我認爲這並不工作:避免嵌套並行區域
#include <omp.h>
#include <stdio.h>
int m=0,s=0;
void func()
{
bool p = omp_in_parallel();
// if clause to suppress nested parallelism
#pragma omp parallel if(!p)
{
/* do some massive work in parallel */
#pragma omp master
++m;
#pragma omp single
++s;
}
}
int main()
{
fprintf(stderr,"running func() serial:\n");
m=s=0;
func();
fprintf(stderr," m=%d s=%d\n",m,s);
fprintf(stderr,"running func() parallel:\n");
m=s=0;
#pragma omp parallel
func();
fprintf(stderr," m=%d s=%d\n",m,s);
}
其創建的輸出
running func() serial:
m=1 s=1
running func() parallel:
m=16 s=16
因此,要func()
第一個呼叫工作得很好:m
和s
儘可能地獲得值1,但是在並行區域內第二次調用func()
確實會創建嵌套並行(即每個線程有16個團隊),儘管這被抑制了。那就是omp master
和omp single
指令綁定到之前的omp parallel if(!p)
指令,而不是綁定到外部並行區域。
當然,人們可以通過下面的代碼
void work()
{
/* do some massive work in parallel */
#pragma omp master
++m;
#pragma omp single
++s;
}
void func()
{
if(omp_in_parallel())
work();
else
#pragma omp parallel
work();
}
解決這個問題,但是這需要一個附加功能進行定義等是否有可能在單個函數內做到這一點(和不重複的代碼) ?
是的,它確實意味着它並不適用於此,因爲通常不能保證(信息隱藏和全部)在外層沒有嵌套並行性。對共享變量進行訪問threadsafe更像是互斥體的用例(omp中的鎖)。你的描述你想如何工作聽起來沒有什麼用處(如果有多個線程調用`do_func`,你只需要其中一個線程(因此調用)寫入全局變量?我不知道你的具體情況,但這聽起來不太有用。 – Grizzly 2011-12-23 02:14:03