#pragma omp task 的疑问

横云断岭
博客专家认证
2010-01-14 09:31:18
先说下我对 #pragma omp task 的理解。
我觉得这个是当有一个线程遇到这个句子时,这个线程就创建一个任务,然后由和这个线程所在的线程组中抽出一个线程来执行这个任务。
在这个任务中变量默认是 private 的。//不知道这个理解对不?
对于下面四个程序,我实在觉得头痛。不知道应该怎样理解。
在我看来,第一个程序应该是正确的,只有一个线程在遍历链表,其它线程在执行process()函数,其中参数e是全局的 Element *e;的一个拷贝。

下面第一个程序是错误的,其它三个是正确的。
List ml; //my_list
Element *e;
#pragma omp parallel
#pragma omp single
{ for(e=ml->first;e;e=e->next)
#pragma omp task
process(e);
}

List ml; //my_list
Element *e;
#pragma omp parallel
#pragma omp single
{ for(e=ml->first;e;e=e->next)
#pragma omp task firstprivate(e)
process(e);
}

List ml; //my_list
Element *e;
#pragma omp parallel
#pragma omp single private(e)
{
for(e=ml->first;e;e=e->next)
#pragma omp task
process(e);
}

List ml; //my_list
#pragma omp parallel
{
Element *e;
for(e=ml->first;e;e=e->next)
#pragma omp task
process(e);
}

...全文
921 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
liuyali 2010-01-17
  • 打赏
  • 举报
回复
#9楼
1)sum是共享的,在并行区(parallel)之外的有效变量都是共享的.

2)你这个code有错误吧! sum在并行区内不能直接 ++sum
应该atom 或critical一下!
intel_iclifort 2010-01-15
  • 打赏
  • 举报
回复
缺省是共享的, 比较一和三的区别.
横云断岭 2010-01-15
  • 打赏
  • 举报
回复
OpenMP程序中所有的线程共享一个全局堆,在堆上的变量是共享的。
每个线程都有自己的栈,在栈上分配的变量是私有的。
//这个正确吧?
要是按照这个原则,比较容易理解y456789的说法。
但是如果按照这个原则,下面这个程序我又不可以理解。
这个程序中sum应该是分配在主线程的栈上,为什么其它线程可以共享?

int main()
{
int sum = 0;
#pragma omp parallel for
for(int i = 0;i<5;++i)
++sum;

cout<<sum;
}
横云断岭 2010-01-15
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 intel_jeff 的回复:]
你没看到我写的最后一句话吧?对于i,j(也就是你的x,y)来说,默认是私有,而在这个例子中需要他们是共享的,所以要加shared,不加shared自然结果就不对了。。。
[/Quote]
你的意思是在这个代码中,整个fib()函数都是并行区?
int fib ( int n )
{

int x ,y;
if ( n < 2 ) return n;
#pragma omp task //shared(x)
{
x = fib(n-1);
}
#pragma omp task// shared(y)
y = fib(n-2);
#pragma omp taskwait
return x+y;
}


int main()
{
cout<<fib(5);
}
intel_jeff 2010-01-15
  • 打赏
  • 举报
回复
你没看到我写的最后一句话吧?对于i,j(也就是你的x,y)来说,默认是私有,而在这个例子中需要他们是共享的,所以要加shared,不加shared自然结果就不对了。。。
y456789 2010-01-15
  • 打赏
  • 举报
回复
因为你的主线程要用到task的结果.
y456789 2010-01-15
  • 打赏
  • 举报
回复
C/C++ codeint fib ( int n )
{

int x ,y;
if ( n < 2 ) return n;
#pragma omp task //shared(x)
{
x = fib(n-1);
}
#pragma omp task// shared(y)
y = fib(n-2);
#pragma omp taskwait
return x+y;
}


int main()
{
cout<<fib(5);
}

这里的x,y是主线程内部创建的,即是主线程私有的,需要把x,y共享给主线程创建的task.
横云断岭 2010-01-15
  • 打赏
  • 举报
回复
可是对于这样的写法,如果不加share()语句是不正确的。
int fib ( int n )
{

int x ,y;
if ( n < 2 ) return n;
#pragma omp task //shared(x)
{
x = fib(n-1);
}
#pragma omp task// shared(y)
y = fib(n-2);
#pragma omp taskwait
return x+y;
}


int main()
{
cout<<fib(5);
}
intel_jeff 2010-01-15
  • 打赏
  • 举报
回复
关于变量默认是共享的还是私有的,OpenMP有一个原则:并行区内声明的变量默认为私有,并行区外声明的变量默认为共享。

LS的fib例子看似shared()多余了,其实不然,看一下完整的fib例子:
#include <stdio.h>
#include <omp.h>
int fib(int n)
{
int i, j;
if (n<2)
return n;
else
{
#pragma omp task shared(i) firstprivate(n)
i=fib(n-1);

#pragma omp task shared(j) firstprivate(n)
j=fib(n-2);

#pragma omp taskwait
return i+j;
}
}

int main()
{
int n = 10;

omp_set_dynamic(0);
omp_set_num_threads(4);

#pragma omp parallel shared(n)
{
#pragma omp single
printf ("fib(%d) = %d\n", n, fib(n));
}
}

变量i,j都是在并行区(该并行区是在main函数里开出来)声明的变量,自然默认是私有的,而要把它转变成共享的,需要显式加上一个 shared()
横云断岭 2010-01-15
  • 打赏
  • 举报
回复
缺省是共享的?
那为什么这个程序一定要加上 shared() 语句?
int fib ( int n )
{
int x,y;
if ( n < 2 ) return n;
#pragma omp task shared(x)
x = fib(n-1);
#pragma omp task shared(y)
y = fib(n-2);
#pragma omp taskwait
return x+y;
}

对于第三个程序,#pragma omp single private(e)
这句中的 private(e) 说明的是对于所有的线程 e 都是private的,还是只是对执行single指明的语句块的线程是private的?
对于上面的第四个程序,我也不理解。
我的理解是:
#pragma omp parallel 语句说明了并行区域的开始,则应该是把 {} 里面的代码复制给每一个线程。这样应该是每个线程都会执行一次历遍链表的操作。

567

社区成员

发帖
与我相关
我的任务
社区描述
英特尔® 边缘计算,聚焦于边缘计算、AI、IoT等领域,为开发者提供丰富的开发资源、创新技术、解决方案与行业活动。
社区管理员
  • 英特尔技术社区
  • shere_lin
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧