这个答案可能有些晚了,但我看到没有人提供准确的说明。
回答您的问题,不,一个线程不会使用一半的核心。一个线程可以在核心内工作,但一个线程可以饱和整个核心的处理能力。
假设线程1和线程2属于0号核心。线程1可以饱和整个核的处理能力,而线程2等待另一个线程结束执行。这是串行执行,而不是并行执行。
乍一看,多余的线程似乎毫无用处。我的意思是,核心每次只能处理一个线程,对吗?
正确,但有些情况下,由于两个重要因素,核心实际上处于空闲状态:
缓存未命中
当CPU接收到任务时,它在自己的缓存中搜索需要处理的内存地址。在许多情况下,内存数据如此分散,以至于不可能将所有所需的地址范围保留在缓存中(因为缓存具有有限的容量)。
当CPU在缓存中找不到所需的内容时,它必须访问RAM。RAM本身是快速的,但与CPU上的die cache相比,它还是不及格的。这里的主要问题是RAM的延迟。
在RAM被访问时,核心就会停滞不前。它什么也不做。这不明显,因为所有这些组件都以荒谬的速度工作,您无法通过一些CPU负载软件注意到它,但它会叠加增加。一个缓存未命中接着一个缓存未命中,整体性能下降相当明显。这就是第二个线程发挥作用的地方。当核心停滞等待数据时,第二个线程进来使得核心保持繁忙状态。因此,您可以基本上抵消核心停滞的性能影响。
我说“基本上”,因为如果发生另一个缓存未命中,第二个线程也可能会使核心停滞,但两个线程连续错过缓存的可能性要小得多。
分支预测失误
分支预测是指在代码路径有多个可能结果时的处理方式。最基本的分支代码是if
语句。
现代CPU内置分支预测算法,试图预测一段代码的执行路径。这些预测器相当复杂,虽然我没有准确的预测成功率数据,但我记得以前有篇文章说英特尔Sandy Bridge架构的平均分支预测成功率超过90%。
当CPU遇到一段分支代码时,它实际上会选择一个路径(预测器认为是正确的路径)并执行它。同时,核心的另一部分评估分支表达式,以查看分支预测是否正确。这被称为推测执行。
这类似于2个不同的线程:一个评估表达式,另一个预先执行可能的路径之一。
从这里我们有两种可能的情况:
- 预测器是正确的。执行从正在执行推测的分支正常继续,而代码路径正在进行决策。
- 预测器是错误的。整个正在处理错误分支的管道必须被清除,并从正确的分支重新开始。
或者,可用的线程可以进入并在解决误判引起混乱时执行。这是超线程的第二个用途。
分支预测平均加速了执行,因为其成功率非常高。但是当预测出错时,性能确实会受到相当大的惩罚。
分支预测不是性能降低的主要因素,因为如我所说,正确预测率相当高。
但缓存未命中在某些情况下仍然是一个问题,并将继续成为一个问题。
根据我的经验,在3D渲染方面,超线程确实有很大帮助(我以此为爱好)。根据场景的大小和所需材质/纹理的不同,我注意到提高了20-30%的性能。巨大场景使用大量RAM,从而使缓存未命中更容易发生。超线程在克服这些未命中方面帮助很大。