我想写一个函数,它使用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