超线程处理器内核能否同时执行两个线程?
Can a hyper-threaded processor core execute two threads at the exact same time?
我很难理解超线程。如果逻辑核心实际上不存在,那么使用超线程有什么意义?。 wikipedia 文章指出:
For each processor core that is physically present, the operating system addresses two virtual (logical) cores and shares the workload between them when possible.
如果两个逻辑核心共享同一个执行单元,这意味着一个线程将不得不暂停,而另一个线程执行,也就是说,我不明白超线程有什么用,因为您实际上并没有引入新的执行单元。我无法解决这个问题
请参阅 my answer on a softwareengineering.SE question for some details about how modern CPUs find and exploit instruction-level parallelism (ILP) 一次 运行 多个指令。 (包括英特尔 Haswell 管道的框图,以及指向更多 CPU 微体系结构详细信息的链接)。还有 现代微处理器
90 分钟指南!
你有一个 CPU 有很多执行单元和一个前端,可以让他们大部分时间都在工作,但只有在良好的条件下。像缓存未命中或分支预测错误这样的停顿,或者只是有限的并行性(例如,一个循环执行一个长链的 FP 添加,在一个(标量或 SIMD)上的 FP 延迟瓶颈每 4 或 5 个时钟添加而不是一个或两个per clock) 将导致每个周期的吞吐量远少于 4 条指令,并使执行单元空闲。
HT(和 Simultaneous Multithreading (SMT) 一般而言)的要点是让那些饥饿的执行单元有工作要做,即使 运行宁代码具有低 ILP 或很多停顿(缓存未命中/分支预测错误)。
SMT 仅向管道添加了一些额外的逻辑,因此它可以同时跟踪两个独立的体系结构上下文。因此,与拥有两倍或四倍的完整内核相比,它的芯片面积和功耗要少得多。 (Knight's Landing Xeon Phi 运行s 4 threads per core,主流Intel CPUs 运行 2.一些非x86芯片运行 8 threads per core,针对数据库-服务器类型的工作负载。)
常见的误解
超线程不是只是优化了上下文切换。在缓存未命中时切换到另一个线程的更简单的设计是可能的,但 HT 比这更高级。
有两个线程处于活动状态时,前端在每个周期(在获取、解码和 issue/rename 阶段)在线程之间交替,但 乱序内核实际上可以在同一周期内从两个逻辑核心执行微指令。
在通常交替的流水线阶段中,只要一个线程停止,另一个线程就会获得该阶段的所有循环。 HT 比固定交替要好得多,因为一个线程可以完成大量工作,而另一个线程正在从分支预测错误中恢复或等待缓存未命中。
请注意,一次最多可以有 10 个缓存未命中(来自 Intel CPUs 中的 L1D 缓存:这是 LFB(行填充缓冲区)的数量,并且内存请求是流水线的。但是如果下一次加载的地址取决于较早的加载(例如,指针在树或链表中追逐),CPU 不知道从哪里加载,也无法保持多个请求在运行中。所以它是实际上对于两个线程并行等待缓存未命中很有用。
有些资源在两个线程处于活动状态时静态分区,有些则竞争共享。参见 this pdf of slides for some details. (For more details about how to actually optimize asm for Intel and AMD CPUs, see Agner Fog's microarchitecture PDF。)
当一个逻辑核心“休眠”(即内核 运行 一条 HLT
指令或任何 MWAIT
进入更深睡眠)时,物理核心转换为单线程模式并让仍然活动的逻辑核心拥有所有资源(包括完整的 ReOrder Buffer 大小和其他静态分区资源),因此它在单线程中查找和利用 ILP 的能力仍然 运行ning 增加更多与其他线程因高速缓存未命中而停止相比。
顺便说一句,某些工作负载实际上 运行 使用 HT 时速度较慢。如果您的工作集勉强适合 L2 或 L1D 缓存,那么 运行 在同一个内核上使用两个将导致更多的缓存未命中。对于已经可以保持执行单元饱和的非常好的高吞吐量代码
(就像高性能计算中的优化矩阵乘法),禁用 HT 是有意义的。始终基准。
在 Skylake 上,我发现在我的四核 i7-6700k 上,视频编码(使用 x265 -preset slower
,1080p)使用 8 个线程比 4 个线程快 15%。我实际上并没有为 4 线程测试禁用 HT,但是 Linux 的调度程序擅长于不反弹线程,并且 运行 在单独的物理内核上有足够的线程时。考虑到 x265 有很多手写的 asm 和 运行 非常高的每周期指令,即使它有一个完整的内核,15% 的加速也相当不错。 (像我使用的较慢的预设往往比 CPU 受内存限制更多。)
我很难理解超线程。如果逻辑核心实际上不存在,那么使用超线程有什么意义?。 wikipedia 文章指出:
For each processor core that is physically present, the operating system addresses two virtual (logical) cores and shares the workload between them when possible.
如果两个逻辑核心共享同一个执行单元,这意味着一个线程将不得不暂停,而另一个线程执行,也就是说,我不明白超线程有什么用,因为您实际上并没有引入新的执行单元。我无法解决这个问题
请参阅 my answer on a softwareengineering.SE question for some details about how modern CPUs find and exploit instruction-level parallelism (ILP) 一次 运行 多个指令。 (包括英特尔 Haswell 管道的框图,以及指向更多 CPU 微体系结构详细信息的链接)。还有 现代微处理器 90 分钟指南!
你有一个 CPU 有很多执行单元和一个前端,可以让他们大部分时间都在工作,但只有在良好的条件下。像缓存未命中或分支预测错误这样的停顿,或者只是有限的并行性(例如,一个循环执行一个长链的 FP 添加,在一个(标量或 SIMD)上的 FP 延迟瓶颈每 4 或 5 个时钟添加而不是一个或两个per clock) 将导致每个周期的吞吐量远少于 4 条指令,并使执行单元空闲。
HT(和 Simultaneous Multithreading (SMT) 一般而言)的要点是让那些饥饿的执行单元有工作要做,即使 运行宁代码具有低 ILP 或很多停顿(缓存未命中/分支预测错误)。
SMT 仅向管道添加了一些额外的逻辑,因此它可以同时跟踪两个独立的体系结构上下文。因此,与拥有两倍或四倍的完整内核相比,它的芯片面积和功耗要少得多。 (Knight's Landing Xeon Phi 运行s 4 threads per core,主流Intel CPUs 运行 2.一些非x86芯片运行 8 threads per core,针对数据库-服务器类型的工作负载。)
常见的误解
超线程不是只是优化了上下文切换。在缓存未命中时切换到另一个线程的更简单的设计是可能的,但 HT 比这更高级。
有两个线程处于活动状态时,前端在每个周期(在获取、解码和 issue/rename 阶段)在线程之间交替,但 乱序内核实际上可以在同一周期内从两个逻辑核心执行微指令。
在通常交替的流水线阶段中,只要一个线程停止,另一个线程就会获得该阶段的所有循环。 HT 比固定交替要好得多,因为一个线程可以完成大量工作,而另一个线程正在从分支预测错误中恢复或等待缓存未命中。
请注意,一次最多可以有 10 个缓存未命中(来自 Intel CPUs 中的 L1D 缓存:这是 LFB(行填充缓冲区)的数量,并且内存请求是流水线的。但是如果下一次加载的地址取决于较早的加载(例如,指针在树或链表中追逐),CPU 不知道从哪里加载,也无法保持多个请求在运行中。所以它是实际上对于两个线程并行等待缓存未命中很有用。
有些资源在两个线程处于活动状态时静态分区,有些则竞争共享。参见 this pdf of slides for some details. (For more details about how to actually optimize asm for Intel and AMD CPUs, see Agner Fog's microarchitecture PDF。)
当一个逻辑核心“休眠”(即内核 运行 一条 HLT
指令或任何 MWAIT
进入更深睡眠)时,物理核心转换为单线程模式并让仍然活动的逻辑核心拥有所有资源(包括完整的 ReOrder Buffer 大小和其他静态分区资源),因此它在单线程中查找和利用 ILP 的能力仍然 运行ning 增加更多与其他线程因高速缓存未命中而停止相比。
顺便说一句,某些工作负载实际上 运行 使用 HT 时速度较慢。如果您的工作集勉强适合 L2 或 L1D 缓存,那么 运行 在同一个内核上使用两个将导致更多的缓存未命中。对于已经可以保持执行单元饱和的非常好的高吞吐量代码 (就像高性能计算中的优化矩阵乘法),禁用 HT 是有意义的。始终基准。
在 Skylake 上,我发现在我的四核 i7-6700k 上,视频编码(使用 x265 -preset slower
,1080p)使用 8 个线程比 4 个线程快 15%。我实际上并没有为 4 线程测试禁用 HT,但是 Linux 的调度程序擅长于不反弹线程,并且 运行 在单独的物理内核上有足够的线程时。考虑到 x265 有很多手写的 asm 和 运行 非常高的每周期指令,即使它有一个完整的内核,15% 的加速也相当不错。 (像我使用的较慢的预设往往比 CPU 受内存限制更多。)