#pragma omp parallel for default(none) shared(x) private (y, z, f) ordered
for (i = 0; i < 512; i++) {
#pragma omp ordered
for (y = 0; y < 512; y++) {
for (z = 0, f = 0; z < 512; z++) {
x[f++] = z + i + y;
}
}
}
上述代码运行速度比非SMP执行速度慢约20% 在双核上。没有“#pragma omp ordered”,它比非SMP快约50%。
假设x [f ++]序列必须保持有序形式,因为它稍后会被重复使用。
有序代码可以比单线程更快吗?还有另一种方法可以实现吗?
系统是win32 / mingw-w64。
答案 0 :(得分:2)
它不是真正有序的,因为除了使用f
之外,一次迭代的结果不依赖于前一次。
您可以从f
,i
和y
派生z
吗?看起来你可以。例如:
f = z + y * 512 + i * 512 * 512 + initial_f;
现在您的代码是无序的,您可以从并行化中获得真正的好处。
答案 1 :(得分:0)
由于内存系统的饱和,单线程/核心代码通常比多线程/核心更快。所发生的是单线程所需的内存工作接近或达到内存系统可以提供的极限。添加另一个需要相同工作的线程/核心,并且两个线程/核心都需要共享内存系统可以提供的内容,从而导致等待状态和执行速度变慢
在分析和优化内存工作之后,您可能会达到多线程代码更快的程度。优化需要将数据移动到非共享存储器(即L1和L2高速缓存)中并最小化对共享存储器(L3和RAM)的访问。
优化解决方案或多或少与手头的应用程序无关。这不是微不足道的(虽然一些第三方软件供应商会试图用他们的产品说这是一块蛋糕)。一旦你完成了它,你至少应该学会了应该避免哪些结构以及哪些技术是有用的。
答案 2 :(得分:-1)
你显然依赖于内循环中的共享向量x
。因此,每次访问该变量都必须由OMP进行互操作。难怪“并行”版本比顺序版本慢。
很难建议你改变什么,因为你的代码对我来说毫无意义。您对结果的期望是什么?如果您有ordered
,则x
中的最终结果将是i
设置为511
的值的版本。如果不这样做,则每个单独的条目都是线程获胜者。
你的f
应该做什么?评估时它与w
具有相同的值,不是吗?这只会增加噪音,使其更难理解。