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