超线程四核CPU上运行的单CPU程序

13

我是一名统计模式识别的研究员,经常运行需要多天时间的模拟。我使用Ubuntu 12.04和Linux 3.2.0-24-generic,据我所知,它支持多核和超线程。我使用Intel Core i7 Sandy Bridge Quadcore with HTT,通常会同时运行4个长时间运行的程序。在提问之前,这些是我已经了解的事情:

  • 我的操作系统(Ubuntu 12.04)由于超线程可以检测到8个CPU。
  • 我的操作系统调度程序很聪明,永远不会将两个程序安排在属于同一物理核心的两个逻辑(虚拟)核心上运行,因为操作系统支持SMP(Simultaneous Multi-Threading)。
  • 我已经阅读了维基百科页面中关于超线程的内容。
  • 我已经阅读了HowStuffWorks页面关于Sandy Bridge的内容。

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

非常感谢您的帮助。如果我的问题有不清楚的地方,请让我知道。


通常情况下,您可以在BIOS中关闭超线程。说1/2不正确,因为它可能会为每个队列排队。需要使用超线程打开和关闭运行一些测试。我进行了一些解析和匹配,并发现关闭超线程并使用与核心数量相同的进程是最优的,但您需要在自己的计算中进行测试。 - paparazzo
你说你已经清楚阅读了的这个链接明确描述了超线程和性能。它明确指出,在超线程模式下,一个核心不会使用其容量的1/2。http://en.wikipedia.org/wiki/Hyper_threading -1 - paparazzo
谢谢Blam的帮助。关于你的第二条评论,你能指出维基百科页面上哪里说核心在HT模式下不使用其1/2的容量吗? - Ray
1
超线程通过复制处理器中存储架构状态的某些部分来工作,但不会复制主要执行资源。 - paparazzo
4个回答

15

这个答案可能有些晚了,但我看到没有人提供准确的说明。

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

假设线程1和线程2属于0号核心。线程1可以饱和整个核的处理能力,而线程2等待另一个线程结束执行。这是串行执行,而不是并行执行。

乍一看,多余的线程似乎毫无用处。我的意思是,核心每次只能处理一个线程,对吗?

正确,但有些情况下,由于两个重要因素,核心实际上处于空闲状态:

  • 缓存未命中
  • 分支预测失败

缓存未命中

当CPU接收到任务时,它在自己的缓存中搜索需要处理的内存地址。在许多情况下,内存数据如此分散,以至于不可能将所有所需的地址范围保留在缓存中(因为缓存具有有限的容量)。

当CPU在缓存中找不到所需的内容时,它必须访问RAM。RAM本身是快速的,但与CPU上的die cache相比,它还是不及格的。这里的主要问题是RAM的延迟。

在RAM被访问时,核心就会停滞不前。它什么也不做。这不明显,因为所有这些组件都以荒谬的速度工作,您无法通过一些CPU负载软件注意到它,但它会叠加增加。一个缓存未命中接着一个缓存未命中,整体性能下降相当明显。这就是第二个线程发挥作用的地方。当核心停滞等待数据时,第二个线程进来使得核心保持繁忙状态。因此,您可以基本上抵消核心停滞的性能影响。

我说“基本上”,因为如果发生另一个缓存未命中,第二个线程也可能会使核心停滞,但两个线程连续错过缓存的可能性要小得多。

分支预测失误

分支预测是指在代码路径有多个可能结果时的处理方式。最基本的分支代码是if语句。 现代CPU内置分支预测算法,试图预测一段代码的执行路径。这些预测器相当复杂,虽然我没有准确的预测成功率数据,但我记得以前有篇文章说英特尔Sandy Bridge架构的平均分支预测成功率超过90%。

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

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

  1. 预测器是正确的。执行从正在执行推测的分支正常继续,而代码路径正在进行决策。
  2. 预测器是错误的。整个正在处理错误分支的管道必须被清除,并从正确的分支重新开始。 或者,可用的线程可以进入并在解决误判引起混乱时执行。这是超线程的第二个用途。 分支预测平均加速了执行,因为其成功率非常高。但是当预测出错时,性能确实会受到相当大的惩罚。

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

根据我的经验,在3D渲染方面,超线程确实有很大帮助(我以此为爱好)。根据场景的大小和所需材质/纹理的不同,我注意到提高了20-30%的性能。巨大场景使用大量RAM,从而使缓存未命中更容易发生。超线程在克服这些未命中方面帮助很大。


1
哇,谢谢你的文章!我稍后会再仔细阅读一遍。 - Ray
由于这是我凭记忆说的,我不能保证所有内容都是100%准确的,但这就是大体上的想法。我的朋友,非常欢迎你:)。 - xIcarus
关于缓存未命中:您声称两个线程连续未命中缓存的可能性低于一个。虽然这在理论上是正确的,但也可能会有一点误导性。由于高速缓存一致性,线程1可以访问线程2刚刚访问的内容,因为数据可能位于同一物理核心上。出于相同的原因,线程1可能不会缓存它本来会缓存的所有内容,因为线程2已经“消耗掉”了部分缓存。您还声称巨大的场景加上大量RAM使得缓存未命中更有可能,是的,但主要是由于渲染算法的线性化。 - Waxhead

4

由于您正在运行Linux内核,所以非常幸运,因为调度程序足够智能,可以确保您的任务被分配在物理核心之间。

Linux在内核2.4.17中变得具有超线程意识(参考:http://kerneltrap.org/node/391

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

但是,如前所述,您可以通过在BIOS中禁用超线程并查看启用或禁用超线程时特定工作负载是否运行更快或更慢来进行实验。如果您启动8个任务而不是4个,则可能会发现在超线程上执行8个任务的总执行时间比使用4个任务分别运行两次要快,但是最好的方法是进行实验。祝你好运!


顺便说一句,我想知道是否会有一天有人写道Linux在x.x.x版本中变得自我意识。 - Waxhead

1

如果您真的只需要4个专用核心,您应该能够在BIOS页面中禁用超线程。此外,这一部分我不是很清楚,我相信处理器足够智能,在第二个逻辑核心空闲时可以在单个线程上执行更多工作。


谢谢您的回复!关于您最后一句话,那也是我的猜测。然而,如果第二个逻辑核心处于空闲状态,它会有多少“在单个线程上做更多工作”呢?相比没有超线程的物理核心,它是否仍然会变慢? - Ray
我可以研究理论方面,但实际上你最好启用超线程来运行并观察所需时间,然后再禁用超线程进行比较。 - Thomas
是啊,我想这样做最好。再次感谢。我只是认为英特尔应该明确说明这种事情。我肯定不是唯一想知道这种事情的人吧? - Ray
那么 Ray,你的结果是什么? - Cheng

0
不,这并不完全正确。超线程核心不是两个核心。有些东西可以并行运行,但不能像在两个独立的核心上那样多。

非常感谢您的回复。您所说的“不完全正确”是什么意思?您是指不正确吗?您是想说一个超线程物理核心在运行在其逻辑核心之一的程序时将使用超过一半的容量吗?如果是这样,它会使用多少?它会在该程序上几乎使用所有容量吗?我希望后面的句子是正确的。 - Ray

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接