使用索引寻址模式时的瓶颈
Bottleneck when using indexed addressing modes
我在 Haswell 和 Coffee Lake 机器上进行了以下实验。
说明
cmp rbx, qword ptr [r14+rax]
吞吐量为 0.5(即每个周期 2 条指令)。这符合预期。该指令被解码为一个 µop,随后未层压(参见 ),因此需要两个退休槽。
如果我们添加一条nop
指令
cmp rbx, qword ptr [r14+rax]; nop
我预计吞吐量为 0.75,因为这个序列需要 3 个退休槽,而且后端似乎也没有其他瓶颈。这也是 IACA 报告的吞吐量。然而,实际吞吐量为 1(这与 µops 是来自解码器还是来自 DSB 无关)。这种情况下的瓶颈是什么?
没有变址寻址方式,
cmp rbx, qword ptr [r14]; nop
正如预期的那样,吞吐量为 0.5。
您似乎已经发现了非分层与常规 multi-uop 指令的缺点,也许是在 micro-fused uop 到达头部时与 4-wide issue/rename/allocate 的交互中IDQ.
假设: 可能 un-lamination 产生的两个 uops 必须属于同一问题组,因此 unlaminated; nop
重复只能实现 front-end 每个时钟 3 fused-domain 微指令的吞吐量。
如果 un-lamination 只发生在 IDQ 的头部,当他们到达 alloc/rename 阶段时,这可能是有道理的。而不是将它们添加到 IDQ。要测试 this,我们可以查看 Haswell 上的 LSD(循环缓冲区)容量是否取决于剥离之前或之后的 uop 计数 - 显示包含 55x [=11= 的循环] 从 Haswell 上的 LSD 运行,因此这是强有力的证据表明在 alloc/rename、 而不是 期间发生了 unlamination 在 IDQ 本身中采取多个条目。
相比之下,cmp dword [rip+rel32], 1
首先在解码器中不会 micro-fuse,所以它不会 un-laminate。如果它达到 0.75c 的吞吐量,那将是支持 un-lamination 在同一问题组中需要空间的证据。
也许 times 2 nop; unlaminate
或 times 3 nop
也可能是一个有趣的测试,看看未层压的 uop 是否会自行发出,或者在从问题组中的任何位置延迟后是否可以可靠地再获取 2 个 NOP .从您的 back-to-back cmp
-unlaminate 测试中,我预计我们仍然会看到大多数完整的 4-uop 问题组。
你的问题是提到退休而不是问题。
Retire 至少与 issue 一样宽(从 Core2 到 Skylake 4 宽,Ice Lake 5 宽)。
Sandybridge / Haswell退役4fused-domainuops/clock。 Skylake 可以每个时钟 每个超线程 退出 4 fused-domain 微指令,如果两个逻辑核心都忙,则允许在一个旧的停滞微指令最终完成后更快地释放资源,如加载缓冲区。在single-thread模式下运行时是否可以retire 8/clock还不是100%清楚,我发现有矛盾的说法,在Intel的优化手册中也没有明确的说法。
即使不是不可能,也很难真正造成退休瓶颈(但不是问题)。任何持续流都必须通过发行阶段,这个阶段不比退休更广泛。 (uops_issued.any
的性能计数器表明 un-lamination 发生在发布之前的某个时间点,因此这并不能帮助我们通过 front-end 阻塞比退休所能处理的更多的微指令。除非那是误导;运行 同一物理内核的两个逻辑内核上的同一循环应该具有相同的总体瓶颈,但如果 Skylake 运行速度更快,那将告诉我们并行 SMT 退役有帮助。不太可能,但如果有人想要,可以检查一下排除它。)
This is also the throughput that IACA reports
IACA 的管道模型似乎很天真;我不认为它知道 Sandybridge 的 multiple-of-4-uop 问题效果(例如 6 uop 循环成本与 8 相同)。 IACA 也不知道 Haswell 可以在整个管道中保持 add eax, [rdi+rdx]
micro-fused,因此对不 un-laminate 的索引 uops 的任何分析都是错误的。
我不相信 IACA 除了计算 uops 和对它们将如何分配给端口做出一些疯狂的猜测之外还能做更多的事情。
我在 Haswell 和 Coffee Lake 机器上进行了以下实验。
说明
cmp rbx, qword ptr [r14+rax]
吞吐量为 0.5(即每个周期 2 条指令)。这符合预期。该指令被解码为一个 µop,随后未层压(参见 ),因此需要两个退休槽。
如果我们添加一条nop
指令
cmp rbx, qword ptr [r14+rax]; nop
我预计吞吐量为 0.75,因为这个序列需要 3 个退休槽,而且后端似乎也没有其他瓶颈。这也是 IACA 报告的吞吐量。然而,实际吞吐量为 1(这与 µops 是来自解码器还是来自 DSB 无关)。这种情况下的瓶颈是什么?
没有变址寻址方式,
cmp rbx, qword ptr [r14]; nop
正如预期的那样,吞吐量为 0.5。
您似乎已经发现了非分层与常规 multi-uop 指令的缺点,也许是在 micro-fused uop 到达头部时与 4-wide issue/rename/allocate 的交互中IDQ.
假设: 可能 un-lamination 产生的两个 uops 必须属于同一问题组,因此 unlaminated; nop
重复只能实现 front-end 每个时钟 3 fused-domain 微指令的吞吐量。
如果 un-lamination 只发生在 IDQ 的头部,当他们到达 alloc/rename 阶段时,这可能是有道理的。而不是将它们添加到 IDQ。要测试 this,我们可以查看 Haswell 上的 LSD(循环缓冲区)容量是否取决于剥离之前或之后的 uop 计数 -
相比之下,cmp dword [rip+rel32], 1
首先在解码器中不会 micro-fuse,所以它不会 un-laminate。如果它达到 0.75c 的吞吐量,那将是支持 un-lamination 在同一问题组中需要空间的证据。
也许 times 2 nop; unlaminate
或 times 3 nop
也可能是一个有趣的测试,看看未层压的 uop 是否会自行发出,或者在从问题组中的任何位置延迟后是否可以可靠地再获取 2 个 NOP .从您的 back-to-back cmp
-unlaminate 测试中,我预计我们仍然会看到大多数完整的 4-uop 问题组。
你的问题是提到退休而不是问题。
Retire 至少与 issue 一样宽(从 Core2 到 Skylake 4 宽,Ice Lake 5 宽)。
Sandybridge / Haswell退役4fused-domainuops/clock。 Skylake 可以每个时钟 每个超线程 退出 4 fused-domain 微指令,如果两个逻辑核心都忙,则允许在一个旧的停滞微指令最终完成后更快地释放资源,如加载缓冲区。在single-thread模式下运行时是否可以retire 8/clock还不是100%清楚,我发现有矛盾的说法,在Intel的优化手册中也没有明确的说法。
即使不是不可能,也很难真正造成退休瓶颈(但不是问题)。任何持续流都必须通过发行阶段,这个阶段不比退休更广泛。 (uops_issued.any
的性能计数器表明 un-lamination 发生在发布之前的某个时间点,因此这并不能帮助我们通过 front-end 阻塞比退休所能处理的更多的微指令。除非那是误导;运行 同一物理内核的两个逻辑内核上的同一循环应该具有相同的总体瓶颈,但如果 Skylake 运行速度更快,那将告诉我们并行 SMT 退役有帮助。不太可能,但如果有人想要,可以检查一下排除它。)
This is also the throughput that IACA reports
IACA 的管道模型似乎很天真;我不认为它知道 Sandybridge 的 multiple-of-4-uop 问题效果(例如 6 uop 循环成本与 8 相同)。 IACA 也不知道 Haswell 可以在整个管道中保持 add eax, [rdi+rdx]
micro-fused,因此对不 un-laminate 的索引 uops 的任何分析都是错误的。
我不相信 IACA 除了计算 uops 和对它们将如何分配给端口做出一些疯狂的猜测之外还能做更多的事情。