首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >超线程..。使我的渲染器慢了10倍

超线程..。使我的渲染器慢了10倍
EN

Stack Overflow用户
提问于 2011-01-27 14:45:02
回答 3查看 4.3K关注 0票数 18

执行摘要:如何在代码中指定OpenMP应该只对真正的内核使用线程,即不计算超线程线程?

详细分析:多年来,我在空闲时间编写了一个只有SW的开源渲染器(rasterizer/raytracer)。GPL代码和Windows二进制文件都可以从这里获得:在Windows、Linux、OS/X和BSD下编译并运行良好的https://www.thanassis.space/renderer.html

上个月,我引入了一种射线追踪模式--生成的图片质量飞涨。不幸的是,射线追踪比光栅化慢数量级。为了提高速度,就像我对光栅化器所做的那样,我向射线追踪器添加了OpenMP (和TBB)支持--以方便地使用额外的CPU核心。栅格化和射线追踪都很容易被线程化(每个三角形工作-每个像素工作)。

在家里,与我的Core2Duo,第二核心帮助所有模式-无论是光栅和射线跟踪模式得到了一个加速,是1.85x和1.9x之间。

问题:自然,我很想看到最好的性能(我还“玩”CPU,初步数据自动化系统端口),所以我想要一个坚实的比较基础。我把代码交给了我的一个好朋友,他有一台“野兽”机器,有一个16核、1500美元的英特尔超级处理器。

他在“最重”模式下运行,射线追踪模式.

...and他的速度是我的Core2Duo的五分之一(!)

气喘吁吁的恐怖。刚才发生了什么?

我们开始尝试不同的修改补丁..。最终我们找到了答案。

通过使用OMP_NUM_THREADS环境变量,可以控制生成了多少OpenMP线程。当线程数从1增加到8时,速度增加(接近线性增长)。当我们穿过8,速度开始下降,直到它鼻子下降到五分之一的速度,我的Core2Duo,当所有16个核心被使用!

为什么是8?

因为8是真正核心的数目。另外8人是..。超线程的!

的理论:现在,这对我来说是个新闻--我看到超线程在其他算法中有很大的帮助(高达25%),所以这是出乎意料的。显然,即使每个超线程内核都有自己的寄存器(以及SSE单元?),但是光线追踪器无法利用额外的处理能力。这让我觉得..。

它可能不是处理能力的饥饿-它是内存带宽。

射线追踪器采用包围体层次数据结构,加速射线-三角形交叉口.如果使用超线程核,那么一对中的每个“逻辑核”都试图从该数据结构中的不同位置(即内存中)读取,并且CPU缓存(每对本地)被彻底破坏。至少,这是我的理论-任何最受欢迎的建议。

因此,问题是: OpenMP检测“核心”的数量,并生成与之匹配的线程--也就是说,计算中包括超线程的“核心”。就我而言,这显然会导致灾难性的后果,就速度而言。有人知道如何使用OpenMP API (如果可能的话,可移植的话)只为真正的内核而不是超级线程生成线程吗?

代码是开放的(GPL),可以在上面的链接上使用,请随意在您自己的机器上复制--我猜这将发生在所有超线程CPU中。

请原谅这篇文章的篇幅,我认为这是一次教育经验,我想分享一下。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-01-27 22:50:41

基本上,您需要一些相当可移植的方式来查询环境中相当低级的硬件细节--通常,您不能仅仅通过系统调用(操作系统甚至不知道硬件线程和内核之间的区别)。

一个支持多种平台的库是黄岩山 --支持Linux和windows (以及其他)、英特尔和和芯片。Hwloc将让您找到有关硬件拓扑的所有信息,并了解内核和硬件线程之间的区别(在hwloc术语中称为PUs处理单元)。因此,您可以在开始时调用这个库,查找实际内核的数量,并调用omp_set_num_threads() (或者在并行部分的开头添加该变量作为指令)。

票数 6
EN

Stack Overflow用户

发布于 2011-01-27 16:07:12

不幸的是,你关于这种情况发生的原因的假设很可能是正确的。可以肯定的是,你必须使用一个配置文件工具-但我以前见过这种与射线跟踪,所以这是不足为奇的。在任何情况下,目前都无法从OpenMP中确定某些处理器是“真实的”,而有些是超线程的。您可以编写一些代码来确定这一点,然后自己设置数字。但是,仍然存在这样的问题,即OpenMP没有安排处理器本身上的线程--它允许操作系统这样做。

OpenMP ARB语言委员会一直在努力为用户定义一种标准的方法来确定他的环境并说明如何运行。在这个时候,这个讨论还在继续。许多实现允许您通过使用实现定义的环境变量将线程“绑定”到处理器。然而,用户必须知道处理器编号以及哪些处理器是“真实的”还是超线程的。

票数 3
EN

Stack Overflow用户

发布于 2011-06-04 10:17:16

问题在于OMP是如何使用HT的。这不是内存带宽!我在2.6GHz的HT上尝试了简单的循环。结果太棒了..。

与OMP:

代码语言:javascript
复制
    $ time ./a.out 
    4500000000
    real    0m28.360s
    user    0m52.727s
    sys 0m0.064s

无OMP:$ time ./a.out 4500000000

代码语言:javascript
复制
    real0   m25.417s
    user    0m25.398s
    sys 0m0.000s

代码:

代码语言:javascript
复制
    #include <stdio.h>
    #define U64 unsigned long long
    int main() {
      U64 i;
      U64 N = 1000000000ULL; 
      U64 k = 0;
      #pragma omp parallel for reduction(+:k)
      for (i = 0; i < N; i++) 
      {
        k += i%10; // last digit
      }
      printf ("%llu\n", k);
      return 0;
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4817789

复制
相关文章

相似问题

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