状态资源的复制是否被认为是超线程的最佳选择?
Is duplication of state resources considered optimal for hyper-threading?
This question has an answer 表示:
Hyper-threading duplicates internal resources to reduce context switch
time. Resources can be: Registers, arithmetic unit, cache.
为什么 CPU 设计人员最终会 复制 状态资源用于同步多线程(或 Intel 上的超线程)?
为什么三倍(四倍等)那些相同的资源不会给我们三个逻辑核心,因此,即使更快的吞吐量?
研究人员得出的重复在某种意义上是最佳,还是只是反映了当前的可能性(晶体管尺寸等)?
您引用的答案听起来有误。超线程 竞争性地共享 现有的 ALU、缓存和物理寄存器文件。
运行 同一个核心上的两个线程让它找到更多的并行性来让这些执行单元有工作,而不是闲置等待缓存未命中、延迟和分支预测错误。 (参见 现代微处理器
90 分钟指南! 非常有用的背景知识,以及关于 SMT 的部分。另外 this answer 了解更多关于现代超标量/乱序 CPU 如何发现和利用指令级并行性以 运行 每个时钟超过 1 条指令的信息。)
只有少数东西需要物理复制或分区来跟踪一个核心中两个 CPU 的架构状态,而且大部分在前端(在 issue/rename 阶段之前). David Kanter's Haswell writeup shows how Sandybridge always partitioned the IDQ (decoded-uop queue that feeds the issue/rename stage), but IvyBridge and Haswell can use it as one big queue when only a single thread is active. He also describes how cache is competitively shared between threads. For example, a Haswell core has 168 physical integer registers,但是每个逻辑CPU的架构状态只需要16个。(每个线程的乱序执行当然受益于很多寄存器,这就是为什么寄存器重命名到一个大的物理寄存器文件首先完成。)
有些东西是静态分区的,比如 ROB,以阻止一个线程用依赖于缓存未命中负载的工作填满后端。
现代英特尔 CPUs 有太多的执行单元,你只能用没有任何停顿的仔细调整的代码勉强饱和它们,运行s 每个时钟 4 个融合域 uops .这在实践中非常罕见,除了在手动调整的 BLAS 库中的矩阵乘法之外。
大多数代码都受益于超线程,因为它无法靠自己使整个内核饱和,因此单个内核的现有资源可以 运行 两个线程,每个线程的速度都快于一半。 (通常明显快于一半)。
但是当只有一个线程 运行ning 时,该线程可以使用大核心的全部功能。如果您设计具有许多小内核的多核 CPU,这就是您所失去的。如果英特尔 CPUs 没有实现超线程,他们可能不会为单个线程包含这么多执行单元。它有助于一些单线程工作负载,但对 HT 的帮助更大。所以你可以争辩说这是一个复制ALU的案例,因为设计支持HT,但这不是必需的。
Pentium 4 确实没有足够的执行资源来 运行 两个完整的线程而不失多得。其中一部分可能是跟踪缓存,但它也几乎没有执行单元的数量。带有 HT 的 P4 使得使用预取线程非常有用,这些线程除了从主线程正在循环的数组中预取数据外什么都不做,如 What Every Programmer Should Know About Memory 中的 described/recommended(这在其他方面仍然有用且相关)。预取线程具有较小的跟踪缓存占用空间,并获取到主线程使用的 L1D 缓存中。这就是当您在没有足够执行资源的情况下实现 HT 以使其真正变得更好时会发生的情况。
HT 对于通过每个物理核心一个线程实现非常高的吞吐量的代码根本没有帮助。例如,饱和 4 微指令/时钟周期的前端带宽而不会停止。
或者,如果您的代码仅在内核的峰值 FMA 吞吐量或其他方面出现瓶颈(使用 10 个向量累加器保持 10 个 FMA 运行)。由于与另一个线程在 L1D 和 L2 缓存中竞争 space 导致的额外缓存未命中,它甚至会伤害到代码最终会减慢很多。 (还有 uop 缓存和 L1I 缓存)。
使 FMA 饱和并对结果进行处理通常需要 vfma...
以外的一些指令,因此高吞吐量 FP 代码通常也接近于使前端饱和。
Agner Fog's microarch pdf 对于非常仔细调整的代码没有从 HT 中获益,甚至被它伤害的情况也是如此。
Paul Clayton 对这个问题的评论也对一般的 SMT 设计提出了一些好的观点。
如果您有不同的线程做不同的事情,SMT 仍然有用。例如高吞吐量 FP 代码与一个线程共享一个核心,该线程主要执行整数工作并且在分支和缓存未命中时停顿很多,可以获得显着的整体吞吐量。低吞吐量线程在大部分时间都没有使用大部分核心,因此 运行 使用另一个线程来使用核心前端和后端资源的另外 80% 可能非常好。
This question has an answer 表示:
Hyper-threading duplicates internal resources to reduce context switch time. Resources can be: Registers, arithmetic unit, cache.
为什么 CPU 设计人员最终会 复制 状态资源用于同步多线程(或 Intel 上的超线程)?
为什么三倍(四倍等)那些相同的资源不会给我们三个逻辑核心,因此,即使更快的吞吐量?
研究人员得出的重复在某种意义上是最佳,还是只是反映了当前的可能性(晶体管尺寸等)?
您引用的答案听起来有误。超线程 竞争性地共享 现有的 ALU、缓存和物理寄存器文件。
运行 同一个核心上的两个线程让它找到更多的并行性来让这些执行单元有工作,而不是闲置等待缓存未命中、延迟和分支预测错误。 (参见 现代微处理器 90 分钟指南! 非常有用的背景知识,以及关于 SMT 的部分。另外 this answer 了解更多关于现代超标量/乱序 CPU 如何发现和利用指令级并行性以 运行 每个时钟超过 1 条指令的信息。)
只有少数东西需要物理复制或分区来跟踪一个核心中两个 CPU 的架构状态,而且大部分在前端(在 issue/rename 阶段之前). David Kanter's Haswell writeup shows how Sandybridge always partitioned the IDQ (decoded-uop queue that feeds the issue/rename stage), but IvyBridge and Haswell can use it as one big queue when only a single thread is active. He also describes how cache is competitively shared between threads. For example, a Haswell core has 168 physical integer registers,但是每个逻辑CPU的架构状态只需要16个。(每个线程的乱序执行当然受益于很多寄存器,这就是为什么寄存器重命名到一个大的物理寄存器文件首先完成。)
有些东西是静态分区的,比如 ROB,以阻止一个线程用依赖于缓存未命中负载的工作填满后端。
现代英特尔 CPUs 有太多的执行单元,你只能用没有任何停顿的仔细调整的代码勉强饱和它们,运行s 每个时钟 4 个融合域 uops .这在实践中非常罕见,除了在手动调整的 BLAS 库中的矩阵乘法之外。
大多数代码都受益于超线程,因为它无法靠自己使整个内核饱和,因此单个内核的现有资源可以 运行 两个线程,每个线程的速度都快于一半。 (通常明显快于一半)。
但是当只有一个线程 运行ning 时,该线程可以使用大核心的全部功能。如果您设计具有许多小内核的多核 CPU,这就是您所失去的。如果英特尔 CPUs 没有实现超线程,他们可能不会为单个线程包含这么多执行单元。它有助于一些单线程工作负载,但对 HT 的帮助更大。所以你可以争辩说这是一个复制ALU的案例,因为设计支持HT,但这不是必需的。
Pentium 4 确实没有足够的执行资源来 运行 两个完整的线程而不失多得。其中一部分可能是跟踪缓存,但它也几乎没有执行单元的数量。带有 HT 的 P4 使得使用预取线程非常有用,这些线程除了从主线程正在循环的数组中预取数据外什么都不做,如 What Every Programmer Should Know About Memory 中的 described/recommended(这在其他方面仍然有用且相关)。预取线程具有较小的跟踪缓存占用空间,并获取到主线程使用的 L1D 缓存中。这就是当您在没有足够执行资源的情况下实现 HT 以使其真正变得更好时会发生的情况。
HT 对于通过每个物理核心一个线程实现非常高的吞吐量的代码根本没有帮助。例如,饱和 4 微指令/时钟周期的前端带宽而不会停止。
或者,如果您的代码仅在内核的峰值 FMA 吞吐量或其他方面出现瓶颈(使用 10 个向量累加器保持 10 个 FMA 运行)。由于与另一个线程在 L1D 和 L2 缓存中竞争 space 导致的额外缓存未命中,它甚至会伤害到代码最终会减慢很多。 (还有 uop 缓存和 L1I 缓存)。
使 FMA 饱和并对结果进行处理通常需要 vfma...
以外的一些指令,因此高吞吐量 FP 代码通常也接近于使前端饱和。
Agner Fog's microarch pdf 对于非常仔细调整的代码没有从 HT 中获益,甚至被它伤害的情况也是如此。
Paul Clayton 对这个问题的评论也对一般的 SMT 设计提出了一些好的观点。
如果您有不同的线程做不同的事情,SMT 仍然有用。例如高吞吐量 FP 代码与一个线程共享一个核心,该线程主要执行整数工作并且在分支和缓存未命中时停顿很多,可以获得显着的整体吞吐量。低吞吐量线程在大部分时间都没有使用大部分核心,因此 运行 使用另一个线程来使用核心前端和后端资源的另外 80% 可能非常好。