首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenMP在i7和Xeon上的意外结果

OpenMP在i7和Xeon上的意外结果
EN

Stack Overflow用户
提问于 2010-11-03 12:38:55
回答 3查看 645关注 0票数 3

并行两个嵌套的for-循环,我遇到了我无法解释的行为。我在OpenMP 860和xeon E5540上尝试了三种不同类型的并行化,我希望代码在这两个平台上的行为大致相同,这意味着对于我测试的所有三种不同的情况,其中一个平台应该更快。但情况并非如此:

  • 对于案例1,Xeon快于10%,
  • 用于case 2,i7按2因子加快,
  • 对于案例3,Xeon又快于1,5

因子。

你知道是什么导致的吗?

请说明您何时需要更多的信息或澄清!

为了进一步澄清,我的问题意味着更笼统。如果我在i7和xeon系统上运行相同的代码,那么使用OpenMP不应该产生可比较的(比例的)结果吗?

伪码:

代码语言:javascript
复制
for 1:4
    for 1:1000
        vector_multiplication
    end
end

的案例:

案例1:没有pramga omp没有并行化

案例2:第一个for -循环的pragma omp

案例3:第二个for -循环的pragma omp

结果

下面是time命令中的实际数字:

案例1

代码语言:javascript
复制
Time   Xeon        i7
real   11m14.120s  12m53.679s
user   11m14.030s  12m46.220s
sys      0m0.080s    0m0.176s

案例2

代码语言:javascript
复制
Time   Xeon        i7
real    8m57.144s   4m37.859s
user   71m10.530s  29m07.797s
sys      0m0.300s   0m00.128s

案例3

代码语言:javascript
复制
Time   Xeon        i7
real    2m00.234s   3m35.866s
user   11m52.870s  22m10.799s
sys     0m00.170s   0m00.136s

更新

谢谢你的提示。我还在研究原因是什么。

EN

回答 3

Stack Overflow用户

发布于 2010-11-03 21:42:45

这里已经有了很好的答案,关于编译效果的可能变化,等等,这是非常正确的;但是还有其他的理由来期待差异。像这样简单明了(例如,低算术强度)的计算往往对内存带宽非常敏感;每个线程可用内存带宽的数量将取决于您运行的线程数。在这两个系统上,内存的设置是否都是相同的?

看起来i7 860的时钟速度更快,但E5540的总内存带宽更高。由于case 2只能使用4个线程,而case 3可以使用更多的线程,因此认为在4线程情况下时钟速度获胜并不疯狂,但是在8线程情况下,增加的内存争用(8个线程试图拉入/推送值)将手指向高带宽的Xeon。

更复杂的是,看起来你在运行8个线程--这些是双套接字系统,还是你在使用超线程?这使得情况更加复杂,因为超线程实际上帮助隐藏了一些内存争用,在另一个线程等待内存时切换到线程中。

如果你想看看有限内存带宽是否在这里起作用,你可以人为地给问题增加更多的计算(例如,把exp(sin(a))乘以cos(b)*cos(b)或其他什么东西),以确保问题是计算界的,当你试图找出问题的根源时,可以去掉一个变量。在每个系统上编译代码,并对该特定机器进行优化(使用-march或-xHost或其他什么)消除了另一个变量。如果超线程打开,关闭它(或者仅仅将OMP_NUM_THREADS设置为物理内核的数量)就会删除另一个变量。一旦你了解了在这个简化的情况下发生了什么,一个接一个地放松上面的限制会帮助你更好地理解正在发生的事情。

票数 2
EN

Stack Overflow用户

发布于 2010-11-03 14:52:55

影响openMP效率的因素是迭代界的计算。确保这些都是事先计算出来的,并且迭代变量尽可能是局部的。如果你让C99做类似的事情

代码语言:javascript
复制
#pragma omp parallel for
for (size_t i = start, is = stop; i < is; ++i) ...

以确保表达式startstop在开始时得到计算。(或者使用_Pragma,请参阅我的另一个答案。)

那么唯一的方法是查看汇编程序代码(通常是选项-S),以确定它是否真的成功。

如果没有查看其他编译器选项。gcc有一个选项-march=native,它为实际的体系结构进行优化编译。其他平台也可能有类似的选择。从为案例1搜索最佳架构选项开始。

票数 0
EN

Stack Overflow用户

发布于 2010-11-03 16:32:57

这与其说是回答,不如说是评论。

还不完全清楚你测量的是什么。为了获得更大的确定性,我想:

  1. 在代码中的点插入计时语句以报告执行时间。这样,我就知道我在测量什么,比Linux time命令给我的更确切。
  2. 使用了两个不同的编译器,以确保我测量的是关于OpenMP的一些内容,而不是它的一个实现的方面。

撇开这一切不说,我倾向于同意你的初步结果需要进一步调查。

我建议您尝试的一件事是折叠您的两个循环,让OpenMP调度4000循环而不是4或1000循环。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4087094

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档