2

如果我对 x86 cpu 的理解正确,那么超线程是有益的,尤其是当我们进行 IO 调用时,这样当阻塞线程空闲时,另一个线程可以在同一个 CPU 上廉价地工作。我的问题是缓存未命中是否也会发生同样的事情。那么在等待数百个周期从主内存中获取数据时,其他线程可以在同一个物理 CPU 上执行一些代码吗?

4

2 回答 2

6

答案是——是的,在一定范围内。

超线程确实允许您对两个程序上下文(操作系统可以附加软件线程)进行细粒度的交错。来自两个线程的指令和缓存数据将同时共存于内核中。

现在,在现代 CPU 中,您不仅仅拥有一个大管道,您可以在每个周期的开始进行仲裁。相反,每个单元(内存单元、缓存、执行单元、乱序组件等)都有自己的管道和与其他单元的通信通道。其中一些单元被分区以支持 2 个线程,并且可以在每个周期中选择从哪里获取下一个任务(假设它们有单独的传入队列可供选择)。其他单元可能在线程之间重复,或者根据其他指标进行仲裁,如果当然是特定于实现的确切选择,但是只要有线程仲裁,硬件就​​会尝试平衡选择(例如进行循环) .

说一个线程停顿了也不简单,一个有未决内存请求的线程可能仍然会提前取回,甚至执行不依赖的操作。从分支错误预测中恢复的线程已经可以提前预取正确的路径——事情总是会完成的。但是,在任何给定的单元上,您可能会发现一个线程确实被卡住了,在这种情况下,仲裁通常会支持另一个线程。因此,当一个线程在 CPU 的某些部分上无法运行时,另一个线程将有效地获得该资源的更大时间份额。但是,被阻塞的线程可能仍在以限制空闲线程的方式使用该资源的一部分,因此说当一个线程被阻塞时,另一个线程可以自由支配核心甚至某些单元是错误的。它只是获得了更好的份额。

例如,由于您询问了内存访问 - 当一个线程错过缓存并离开(到下一级缓存或主内存)时,所需的数据可能会导致数据依赖停止,从而阻止执行更年轻的指令,并且因此可能会减少未来依赖的内存访问(如果您正在遍历链表,您会被卡住,但如果您正在遍历数组,您甚至不会注意到这一点)。这将为其他线程提供更多的内存单元(以及那里最重要的资源 - 未命中缓冲区以保存需要发送到外部的请求)。从长远来看,它可能会因此表现出更好的性能。

于 2014-12-01T19:37:18.293 回答
1

实际上,线程阻塞是上下文切换的机会,通过它另一个进程或线程将利用第一个线程留下的空闲资源而不需要超线程。

超线程的优势在于一个线程可以使用核心中的众多执行单元,而另一个线程在没有上下文切换的情况下不使用它们。这包括当第一个线程使用第二个线程需要的其他单元时,以及当它因缓存未命中而停止时。

请注意,在乱序处理器中,“等待获取数据”的概念无论如何都不符合现实。理论上可以使用有序内核实现超线程,以明确利用缓存未命中的优势,但我所知道的超线程实例是 Pentium 4 和最近的 Core 变体,它们都是 OOO 处理器。

于 2014-12-01T17:52:34.790 回答