? 请问:openmp这三种实现方法的本质差别

qgdbr08 2009-06-03 08:32:53
我想要在两个功能相似的for循环中使用并行,使用了如下三种方法:
1,并行度:4.53%;使用并行的函数运行时间:78031;

#pragma omp parallel for nowait firstprivate(cipher0,plain,cipher1,Key) private(j)
for(i=0;i<(Nbits_Plaintext-2);i++)
{
plain[i]=1;
for(j=(i+1);j<(Nbits_Plaintext-1);j++)
{
plain[j]=1;
degree_0(cipher0);
desfunc(cipher1,plain,Key);
if(cipher1[j])
{
#pragma omp atomic
num_of_degree[j]++;//InterlockIncrement(&num_of_degree[m]);
}
plain[i]=0;
}
}
#pragma omp parallel for firstprivate(cipher0,plain,cipher1,Key) private(j)
for(i=0;i<(Nbits_Plaintext-2);i++)
{
Key[i]=1;
for(j=(i+1);j<(Nbits_Plaintext-1);j++)
{
Key[j]=1;
degree_0(cipher0);
desfunc(cipher1,plain,Key);
if(cipher1[j])
{
#pragma omp atomic
num_of_degree[j]++;
}
Key[i]=0;
}
}


2,并行度:4.35%;使用并行的函数运行时间:78571;

#pragma omp parallel
{
#pragma omp for nowait firstprivate(cipher0,plain,cipher1,Key) private(j,k,m)
for(i=0;i<(Nbits_Plaintext-2);i++)
{…}
#pragma omp for firstprivate(cipher0,plain,cipher1,Key) private(j,k,m)
for(i=0;i<(Nbits_Plaintext-2);i++)
{…}
}

3, 并行度:5.49%;使用并行的函数运行时间:51453;

#pragma omp parallel firstprivate(cipher0,plain,cipher1,Key) private(i,j,k,m)
{
#pragma omp sections
{
#pragma omp section
{
for(i=0;i<(Nbits_Plaintext-2);i++)
{…}
}
#pragma omp section
{
for(i=0;i<(Nbits_Plaintext-2);i++)
{…}
}
}
}

其中,并行度是由Intel thread profiler分析得到的,而运行时间是根据finish_clock()-start_clock()得到;

问题一:这三种实现方法 在这两个时间参数上 为什么会有这么大的差别??原因何在?
问题二:
#pragma omp atomic
num_of_degree[j]++;
怎么才能运用InterlockIncrement(&num_of_degree[m])实现?像这样的num_of_degree[]全局数组递增 怎样实现能更好一些呢?

谢谢了!
...全文
403 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
yasaka 2012-05-25
  • 打赏
  • 举报
回复
#pragma omp parallel for nowait firstprivate(cipher0,plain,cipher1,Key) private(j)
???
nowait可以和#pragma omp parallel for连用?
fanbin23 2009-06-05
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 qgdbr08 的回复:]
引用 3 楼 fanbin23 的回复:

第一个问题:
是的,每次parallel region都会有…


谢谢你的建议!
事实上 第一种方式的两个时间参数都比第二种方式的好,如果说每次parallel region都会有一次fork/join,那么第一种方式是不是应该进行了两次fork/join? 而第二种我使用了 nowait 是不是没有了implicit barrier??不明白为什么第二种会比第一种效果更差...
[/Quote]

因为不光是#pragma omp parallel,如果你仔细看OpenMP的规范就知道#pragma omp for后面也是有implicit barrier的。所以
#pragma omp parallel
#pragma omp for
这种结构实际上有两个barrier,你在for里用了一个nowait,但外层的parallel的barrier还在,而
#pragma omp parallel for就只有一个implicit barrier了,你用了nowait,就相当于一个也没有了

楼上说的也是可能的造成第二种性能更差的原因
qgdbr08 2009-06-05
  • 打赏
  • 举报
回复
谢谢两位! 后来发现 测试结果我弄错了~ 不小心加了一语句!非常感谢!
cls555 2009-06-04
  • 打赏
  • 举报
回复
确实,每次parallel region都会有implicit barrier
第一种方案barrier之后才会进入下一个region
第二种方案用得是nowait,线程在前一个region结束后立即进入下一个region,下一个region里面用到了同一个互斥变量
这时会和前一个region的线程形成争用,由于线程运行顺序是无法预计的,这种方案的争用存在比第一种方案多的风险

根据实际测试的结果也可以看出这一点,如果你把互斥变量去掉,看看两次运行时间会如何
qgdbr08 2009-06-04
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 fanbin23 的回复:]

第一个问题:
是的,每次parallel region都会有…
[/Quote]

谢谢你的建议!
事实上 第一种方式的两个时间参数都比第二种方式的好,如果说每次parallel region都会有一次fork/join,那么第一种方式是不是应该进行了两次fork/join? 而第二种我使用了 nowait 是不是没有了implicit barrier??不明白为什么第二种会比第一种效果更差...
fanbin23 2009-06-03
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 qgdbr08 的回复:]
谢谢! 可是 用Intel profiler分析第一、二种, 发现 第一种方式的并行过程并不全是两个线程同时执行的,中间有单线程执行过程;而第二种就不会出现单线程的情况;
还有,是不是每个#pragma omp parallel前后都有一次fork/join? 直观告诉我第二种应该比第一种方式好才对,可是Intel profiler分析结果并不是这样...所以 应该是哪里没理解...
[/Quote]

第一个问题:
是的,每次parallel region都会有一次fork/join,但对于一个好的OpenMP实现来说,第一种实现的效率应该不会比第二种更差。实际上反而应该是第二种更差,因为第二种方法多了一次implicit barrier,在worksharing loop之后也是有implicit barrier的。但我猜由于程序绝大部分的开销还是来自atomic,所以没体现出来。

至于为啥sections更快,我倒没看出明显的原因。因为你没说OMP_NUM_THREADS你设成了多少。要是>2的话,可能就是1楼说的原因了,因为sections的版本只有两个线程。而前两个版本就是OMP_NUM_THREADS个线程了

第二个问题:
粗略的看,或许你想办法把那个双重循环做一下interchange,把j循环放到外层做并行,然后用个临时变量代替num_of_degree[j]做reduction可能会有用,否则atomic或许是最好的方法了。一个好的编译器和OpenMP实现会帮你把++变成尽可能快的实现的
qgdbr08 2009-06-03
  • 打赏
  • 举报
回复
谢谢! 可是 用Intel profiler分析第一、二种, 发现 第一种方式的并行过程并不全是两个线程同时执行的,中间有单线程执行过程;而第二种就不会出现单线程的情况;
还有,是不是每个#pragma omp parallel前后都有一次fork/join? 直观告诉我第二种应该比第一种方式好才对,可是Intel profiler分析结果并不是这样...所以 应该是哪里没理解...
cls555 2009-06-03
  • 打赏
  • 举报
回复
第一种和第二种方法没有本质区别,第一种是简写形式
第三种采用section,此时是一个section对应一个线程,这种方式减少了并发时atomic互斥访问等待时间,所以比前两种都要快

567

社区成员

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

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