超线程处理器核心可以在同一时间执行两个线程吗?

Tre*_*rey 1 multithreading cpu-architecture multiprocessing hyperthreading

我很难理解超线程.如果逻辑核心实际上不存在,那么使用超线程有什么意义呢?在维基百科的文章指出:

对于物理上存在的每个处理器核心,操作系统寻址两个虚拟(逻辑)核心,并在可能的情况下共享它们之间的工作负载.

如果两个逻辑内核共享相同的执行单元,这意味着其中一个线程必须被保持而另一个执行,这就是说,我不明白超线程如何有用,因为你是实际上没有引入新的执行单元.我无法绕过这个

Pet*_*des 6

请参阅我关于软件工程的答案.有关现代CPU如何通过一次运行多个指令来查找和利用指令级并行(ILP)的一些详细信息.(包括Intel Haswell管道的框图,以及更多CPU微体系结构细节的链接).

你有一个拥有大量执行单元的CPU和一个前端,可以让它们主要供应工作,但只有在良好的条件下.像高速缓存未命中或分支错误预测一样失速,或者只是有限的并行性(例如,执行一个长链FP添加的循环,FP延迟在一个(标量或SIMD)上的瓶颈每4或5个时钟而不是每个时钟一个或两个时钟)每个周期将导致吞吐量远低于4个指令,并使执行单元空闲.

HT(和一般多线程(SMT))的重点是让那些饥饿的执行单元保持工作,即使运行具有低ILP或大量停顿的代码(缓存未命中/分支错误预测).

SMT只为管道添加了一些额外的逻辑,因此它可以同时跟踪两个独立的架构上下文.因此,与两倍或4倍的全内核相比,它的芯片面积和功耗要低得多.(Knight's Landing Xeon Phi每个核心运行4个线程,主流Intel CPU运行2.一些非x86芯片每个核心运行8个线程,针对数据库服务器类型的工作负载.)


常见的误解

超线程是不是刚刚优化上下文切换.可以在缓存未命中时切换到另一个线程的更简单设计,但HT比这更先进.

在两个线程处于活动状态时,前端在每个周期(在获取,解码和发出/重命名阶段)中在线程之间交替,但是无序核心实际上可以在同一周期中从两个逻辑核心执行uop.

在通常交替的管道阶段中,任何时候一个线程停止,另一个线程获得该阶段的所有周期.HT比固定交替要好得多,因为一个线程可以完成大量工作,而另一个线程从分支错误预测中恢复或等待缓存未命中.

请注意,一次最多可以有10个缓存未命中(来自Intel CPU中的L1D缓存:这是LFB(线路填充缓冲区)的数量,并且内存请求是流水线的.但是如果下一个加载的地址依赖于更早的加载(例如,指针在树或链表中追逐),CPU不知道从哪里加载,也不能保持多个请求在飞行中.因此,两个线程并行等待缓存未命中实际上是有用的.

当两个线程处于活动状态时,某些资源被静态分区,一些资源是竞争性共享的.有关详细信息,请参阅幻灯片的pdf.(有关如何为英特尔和AMD CPU实际优化asm的更多详细信息,请参阅Agner Fog的微体系结构PDF.)


当一个逻辑核心"休眠"(即内核运行HLT指令或其他任何MWAIT进入更深层次的睡眠)时,物理核心转换为单线程模式,并让仍然活跃的逻辑核心拥有所有资源(包括完整的ReOrder缓冲区)大小和其他静态分区资源),因此它能够在仍在运行的单个线程中查找和利用ILP的能力比在缓存未命中时仅停止其他线程的能力增加更多.


顺便说一句,有些工作负载实际上运行速度较慢.如果你的工作集几乎不适合L2或L1D缓存,那么在同一个核心上运行两个将导致更多的缓存未命中.对于可以保持执行单元饱和的非常好的高吞吐量代码(如高性能计算中的优化矩阵乘法),禁用HT是有意义的.总是基准.

在Skylake上,我发现-preset slower在我的四核i7-6700k上,8个线程而不是4个线程的视频编码(x265,1080p )快15%左右.我实际上并没有为4线程测试禁用HT,但Linux的调度程序擅长于在有足够的空间可以绕过线程并在单独的物理内核上运行线程.考虑到x265有很多手写的asm并且每个周期运行非常高的指令,即使它有一个完整的核心,15%的加速也是相当不错的.(像我使用的较慢的预设往往比内存限制更多的CPU限制.)