- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
执行摘要 :
如何在他的代码中指定 OpenMP 应该只将线程用于 REAL 内核,即不计算超线程内核?
详分割析 :多年来,我在空闲时间编写了一个纯软件的开源渲染器(光栅化器/光线跟踪器)。 GPL 代码和 Windows 二进制文件可从此处获得:
https://www.thanassis.space/renderer.html
它在 Windows、Linux、OS/X 和 BSD 下编译和运行良好。
上个月我介绍了一种光线追踪模式 - 生成的图片质量飙升。不幸的是,光线追踪比光栅化慢几个数量级。为了提高速度,就像我对光栅化器所做的那样,我为光线追踪器添加了 OpenMP(和 TBB)支持 - 以轻松利用额外的 CPU 内核。光栅化和光线追踪都可以轻松地进行线程处理(每个三角形的工作量 - 每个像素的工作量)。
在家里,使用我的 Core2Duo,第二个核心帮助了所有模式 - 光栅化和光线追踪模式都获得了 1.85 倍和 1.9 倍之间的加速。
问题:自然,我很想看到顶级 CPU 性能(我也“玩”过 GPU,preliminary CUDA port),所以我想要一个坚实的比较基础。我把代码给了我的一个好 friend ,他可以使用一台“野兽”机器,它有一个 16 核、1500 美元的英特尔 super 处理器。
他以“最重”模式运行它,光线追踪器模式......
...他的速度是我的 Core2Duo 的五分之一(!)
喘息——恐怖。刚刚发生了什么?
我们开始尝试不同的修改、补丁……最终我们弄明白了。
通过使用 OMP_NUM_THREADS 环境变量,可以控制产生多少 OpenMP 线程。
随着线程数从 1 增加到 8,速度也在增加(接近线性增加)。
我们越过 8 的那一刻,速度开始下降,直到它急剧下降到我的 Core2Duo 速度的五分之一,当所有 16 个核心都用完时!
为什么是8?
因为 8 是真正的核心数。其他 8 个是……超线程的!
理论:现在,这对我来说是个新闻——我已经看到超线程在其他算法中的帮助很大(高达 25%),所以这是出乎意料的。显然,即使每个超线程内核都有自己的寄存器(和 SSE 单元?),光线追踪器也无法利用额外的处理能力。这让我想到...
饥饿的可能不是处理能力 - 它是内存带宽。
光线追踪器使用包围体层次结构数据结构来加速光线与三角形的交点。如果使用超线程内核,则一对中的每个“逻辑内核”都试图从该数据结构中的不同位置(即内存中)读取 - 并且 CPU 缓存(每对本地)被完全颠簸。至少,这是我的理论——欢迎提出任何建议。
所以,问题: OpenMP 检测“核心”的数量并生成与之匹配的线程——也就是说,它在计算中包含超线程“核心”。就我而言,这显然会在速度方面导致灾难性的结果。有谁知道如何使用 OpenMP API(如果可能,可移植)只为 REAL 内核生成线程,而不是超线程内核?
附言代码是开放的 (GPL) 并且可以在上面的链接中找到,请随意在您自己的机器上复制 - 我猜这将发生在所有超线程 CPU 中。
附言请原谅帖子的长度,我认为这是一种教育经验并想分享。
最佳答案
基本上,您需要一些相当可移植的方式来查询环境以获取相当低级的硬件细节 - 通常,您不能仅通过系统调用来做到这一点(操作系统通常甚至不知道硬件线程和内核之间的差异)。
一个支持多种平台的库是 hwloc - 支持 Linux & windows (和其他), intel & amd 芯片。 Hwloc 将让您了解有关硬件拓扑的所有信息,并了解内核和硬件线程(称为 PU - 处理单元 - 在 hwloc 术语中)之间的区别。所以你会在开始时调用这个库,找到实际内核的数量,然后调用 omp_set_num_threads() (或者只是将该变量作为指令添加到并行部分的开头)。
关于rendering - 超线程……让我的渲染器慢了 10 倍,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4817789/
在C#中,我可以通过base关键字访问基类,在java中,我可以通过super关键字访问它。在delphi中如何做到这一点?假设我有以下代码: type TForm3 = class(TF
在这件事上我已经把头撞到墙上好几次了。所以我希望在正确的方向上得到一点帮助。 我有一张 table ,上面有订单,一张 table 上有火车,一张 table 上有航类,一张 table 上有巴士。每
在 Python 中,假设我有以下代码: class SuperClass(object): def __init__(self, x): self.x = x
我希望这个 subview 扩展到它的父 View 之外,但是父 View 的边框正在切入 subview 。有没有办法防止这种情况? class TheView : UIView { let
我有一个标准的高斯函数,看起来像这样: def gauss_fnc(x, amp, cen, sigma): return amp * np.exp(-(x - cen) ** 2 / (2
例如,我有下一个类,带有有界类型参数: public class ItemContainer { void addItems(List items); } 在另一个带有参数的类中使用: pub
如何将此设置转换为命令? 结果如下: // Manual Compression (see the image above) Compressed Size: 12,647,451 bytes //
请建议在应用继承时如何使用@Wither/@With。 我有一个抽象类Parent和具体的Child。 Child 应该是不可变的。将 @Wither 放在两者上会给我两个错误: 构造函数 Child
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
我正在尝试向服务器(虚拟托管)发出 HTTP2 请求,该服务器根据主机 header 值 (SNI) 提供 SSL 证书。 # conn = hyper.HTTP20Connection('h
我有一个应用程序,必须将大约 1300 万行、大约 10 个平均长度的字符串插入到嵌入式 HSQLDB 中。我一直在调整一些东西(批量大小、单线程/多线程、缓存/非缓存表、MVCC 事务、log_si
我想定义一个函数f(x, t::Type)根据 isa(x, t) 是否执行不同的行为.假设我想调用b1(x)如果是,b2(x)除此以外。 我知道我可以像这样在运行时进行动态检查: function
我正在使用 Hyper-V WMI Provider在 Hyper-V 中导入虚拟机,特别是使用 ImportVirtualSystemEx Msvm_VirtualSystemManagementS
这几个星期以来一直困扰着我,我没有结束对它的研究,因为我目前重载并且它让我落后于第一年的 CS (opengl) 大学类(class),这首先让我研究了这个:如何只用一个 for 循环绘制立方体的所有
我正在我的计算机(操作系统:Windows 8)上开发一个 WP8 应用程序。我需要安装一个 VM 才能拥有 linux。同时我需要使用我的 Windows Phone 模拟器。 我下载了 VMWar
我是一名优秀的程序员,十分优秀!