【问题标题】:Single-CPU programs running on Hyper-Threading-enabled quadcore CPU在支持超线程的四核 CPU 上运行的单 CPU 程序
【发布时间】:2012-05-22 20:10:59
【问题描述】:

我是统计模式识别方面的研究员,我经常运行运行了很多天的模拟。我正在运行带有 Linux 3.2.0-24-generic 的 Ubuntu 12.04,据我所知,它支持多核和超线程。使用带有 HTT 的 Intel Core i7 Sandy Bridge Quadcore,我经常同时运行 4 个模拟(需要很长时间的程序)。在我提出问题之前,以下是我已经(认为我)知道的事情。

  • 由于超线程,我的操作系统 (Ubuntu 12.04) 检测到 8 个 CPU。
  • 我的操作系统中的调度程序非常聪明,绝不会调度两个程序在属于同一物理内核的两个逻辑(虚拟)内核上运行,因为操作系统支持 SMP(同时多线程)。
  • 我已阅读有关超线程的 Wikipedia 页面。
  • 我已阅读 Sandy Bridge 上的 HowStuffWorks 页面。

好的,我的问题如下。当我在我的计算机上同时运行 4 个模拟(程序)时,它们每个都在一个单独的物理内核上运行。然而,由于超线程,每个物理核心被分成两个逻辑核心。因此,每个物理内核是否只使用其全部容量的一半来运行我的每个模拟?

提前非常感谢您。如果我的问题的任何部分不清楚,请告诉我。

【问题讨论】:

  • 通常您可以在 BIOS 中关闭超线程。说 1/2 是不正确的,因为它可能会为每个排队。需要在打开和关闭超线程的情况下运行一些测试。我做了一些解析和匹配,我发现超标题关闭和与核心一样多的进程是最佳的,但你需要测试你的计算。
  • 您说您阅读的此链接清楚地描述了 HT 和性能。它清楚地表明核心在 HT 模式下不使用其容量的 1/2。 en.wikipedia.org/wiki/Hyper_threading -1
  • 感谢 Blam 的帮助。关于您的第二条评论,您能否指出维基百科页面上的哪个位置说核心在 HT 模式下未使用其容量的 1/2?
  • 超线程通过复制处理器的某些部分(存储架构状态的部分)来工作,但不复制主要的执行资源。

标签: hyperthreading


【解决方案1】:

这个答案可能已经晚了,但我看到没有人准确描述引擎盖下发生的事情。

回答你的问题,不,一个线程不会使用半个核心。 一个线程一次可以在内核内部工作,但是一个线程可以使整个内核处理能力饱和。

假设线程 1 和线程 2 属于核心 #0。线程 1 可以使整个内核的处理能力饱和,而线程 2 则等待另一个线程结束其执行。这是一个序列化的执行,而不是并行的。

乍一看,额外的线程似乎没有用。我的意思是核心可以一次处理 1 个线程,对吗?

正确,但是由于两个重要因素,核心实际上处于空闲状态:

  • 缓存未命中
  • 分支预测错误

缓存未命中

当它收到一个任务时,CPU 在它自己的缓存中搜索它需要使用的内存地址。在许多情况下,内存数据非常分散,以至于物理上不可能将所有需要的地址范围保留在高速缓存内(因为高速缓存确实具有有限的容量)。

当 CPU 在缓存中找不到所需的内容时,它必须访问 RAM。 RAM 本身速度很快,但与 CPU 的片上缓存相比就显得苍白无力。 RAM 的延迟是这里的主要问题。

在访问 RAM 时,内核停止。它什么也没做。这并不明显,因为所有这些组件无论如何都以荒谬的速度工作,并且您不会通过一些 CPU 负载软件注意到它,但它会叠加。一个接一个的缓存未命中和另一个非常明显地阻碍了整体性能。 这是第二个线程发挥作用的地方。当核心停止等待数据时,第二个线程进入以保持核心忙碌。因此,您通常会否定核心停顿对性能的影响。

我说主要是因为如果发生另一个缓存未命中,第二个线程也可以停止核心,但是 2 个线程连续丢失缓存而不是 1 个线程的可能性要低得多。

分支错误预测

分支预测是指您的代码路径包含多个可能的结果。最基本的分支代码是if 语句。 现代 CPU 在其微码中嵌入了分支预测算法,这些算法试图预测一段代码的执行路径。这些预测器实际上非常复杂,虽然我没有关于预测率的可靠数据,但我确实记得前段时间读过一些文章,指出英特尔的 Sandy Bridge 架构的平均成功分支预测率超过 90%。

当 CPU 遇到一段分支代码时,它实际上会选择一条路径(预测器认为正确的路径)并执行它。同时,核心的另一部分评估分支表达式以查看分支预测器是否确实正确。这称为推测执行。 这类似于 2 个不同的线程:一个评估表达式,另一个提前执行可能的路径之一。

从这里我们有两种可能的情况:

  1. 预测器是正确的。在决定代码路径时,从已经在执行的推测分支正常继续执行。
  2. 预测器错误。必须刷新处理错误分支的整个管道并从正确的分支重新开始。 或者,现成的线程可以进来并简单地执行,同时解决由错误预测引起的混乱。这是超线程的第二次使用。 平均而言,分支预测大大加快了执行速度,因为它的成功率非常高。但是当预测错误时,性能确实会受到相当大的惩罚。

分支预测不是性能下降的主要因素,因为正如我所说,正确预测率非常高。 但是缓存未命中是一个问题,并且在某些情况下仍将是一个问题。

根据我的经验,超线程确实对 3D 渲染有很大帮助(我只是出于爱好)。我注意到 20-30% 的改进取决于场景的大小和所需的材料/纹理。巨大的场景使用大量的 RAM,使得缓存未命中的可能性大大增加。超线程有助于克服这些失误。

【讨论】:

  • 哦,哇,谢谢你的文章!稍后我将不得不再次详细阅读。
  • 我不能保证一切都是 100% 准确的,因为这不是我的想法,但这是大体的想法。不客气,我的朋友 :)。
  • 关于缓存未命中:您声称两个线程连续丢失缓存的可能性低于一个。虽然这在理论上可能是正确的,但也可能有点误导。由于缓存一致性,线程 1 可能有权访问线程 2 刚刚访问的内容,因为数据可能位于同一物理内核上。出于同样的原因,线程 1 可能不会缓存它本来会做的所有事情,因为线程 2 已经“吃掉”了缓存的一部分。您还声称,巨大的场景加上大量的 RAM 使得缓存未命中的可能性更大,是的,但主要是由于渲染算法的线性。
【解决方案2】:

由于您在 Linux 内核上运行,因此您很幸运,因为调度程序足够智能,可以确保您的任务在物理内核之间进行分配。

Linux 在内核 2.4.17 中开始支持超线程(参考:http://kerneltrap.org/node/391

请注意,引用来自旧的 O(1) 调度程序。 Linux 现在使用内核 2.6.23 中引入的 CFS 调度算法,应该会更好。

但正如已经建议的那样,您可以通过在 bios 中禁用超线程来进行试验,看看您的特定工作负载在启用或不启用超线程的情况下运行得更快或更慢。如果您启动 8 个任务而不是 4 个任务,您可能会发现超线程上 8 个任务的总执行时间比两次单独运行 4 个任务的总执行时间要快,但最好的办法还是进行试验。祝你好运!

【讨论】:

  • 附注。我想知道是否会有人在 x.x.x 中编写 Linux 变得自我意识 ;)
【解决方案3】:

如果您真的只需要 4 个专用内核,您应该能够在 BIOS 页面中禁用超线程。另外,这部分我不太清楚,我相信处理器足够聪明,如果它的第二个逻辑核心空闲,它可以在单个线程上做更多的工作。

【讨论】:

  • 感谢您的回复!关于你的最后一句话,这也是我的怀疑。但是,“如果第二个逻辑核心空闲,单个线程上的更多工作”会做多少?如果物理内核没有超线程,它仍然会慢吗?
  • 我可以研究理论方面,但实际上最好的办法是在启用超线程的情况下运行并查看需要多长时间,然后在禁用超线程的情况下尝试。
  • 是的,我想最好这样做。再次感谢。我只是认为英特尔会明确说明这种事情。想知道这种事情的人肯定不止我一个?
  • 那么雷,你的结果是什么?
【解决方案4】:

不,这并不完全正确。超线程内核不是两个内核。有些事情可以并行运行,但不如在两个独立的内核上运行。

【讨论】:

  • 您好,非常感谢您的回复。你是什​​么意思“不完全正确”?你的意思是不是真的?您的意思是说,超线程物理内核将在仅在其一个逻辑内核上运行的程序上使用其一半以上的容量?如果是这样,还有多少?它会在该程序上使用几乎所有的容量吗?后一句话是我希望是真的。
猜你喜欢
  • 1970-01-01
  • 2017-08-22
  • 2016-05-08
  • 2018-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多