首页 > 解决方案 > 使用索引寻址模式时的瓶颈

问题描述

我在 Haswell 和 Coffee Lake 机器上进行了以下实验。

该指令

cmp rbx, qword ptr [r14+rax]

吞吐量为 0.5(即每个周期 2 条指令)。这正如预期的那样。该指令被解码为一个稍后未分层的 µop(请参阅https://stackoverflow.com/a/31027695/10461973),因此需要两个退休槽。

如果我们添加一条nop指令

cmp rbx, qword ptr [r14+rax]; nop

我预计吞吐量为 0.75,因为此序列需要 3 个退休槽,而且后端似乎也没有其他瓶颈。这也是 IACA 报告的吞吐量。但是,实际吞吐量为 1(这与微操作来自解码器还是 DSB 无关)。这种情况下的瓶颈是什么?

如果没有索引寻址模式,

cmp rbx, qword ptr [r14]; nop

正如预期的那样,吞吐量为 0.5。

标签: x86-64intelcpu-architecturemicro-optimizationaddressing-mode

解决方案


似乎您已经发现了 unlamination 与常规 multi-uop 指令相比的一个缺点,可能是在与 4-wide issue/rename/allocate 的交互中,当微融合的 uop 到达 IDQ 的头部时。

假设:也许由非分层产生的两个微指令必须属于同一个问题组,因此unlaminated; nop重复只能实现每个时钟 3 个融合域微指令的前端吞吐量。

如果 un-lamination 仅发生在 IDQ 的头部,这可能是有道理的,因为它们到达了分配/重命名阶段。而不是将它们添加到 IDQ 中。为了测试这一点,我们可以查看 Haswell 上的 LSD(循环缓冲区)容量是否取决于 unlamination 之前或之后的 uop 计数 - @AndreasAbel 的测试表明,包含 55x 的循环cmp rbx, [r14+rax]从 Haswell 上的 LSD 运行,因此这是在 alloc 期间发生 unlamination 的有力证据/rename,在 IDQ 本身中不包含多个条目。


为了比较,cmp dword [rip+rel32], 1首先在解码器中不会微熔,因此不会脱膜。如果它达到 0.75c 吞吐量,那将是支持在同一问题组中需要空间的非层压的证据。

也许times 2 nop; unlaminatetimes 3 nop也可能是一个有趣的测试,看看未层压的 uop 是否会自行发布,或者在它从问题组中的任何位置延迟后能否可靠地再获得 2 个 NOP。从您的背靠背非cmp层压测试中,我希望我们仍然会看到大部分完整的 4-uop 问题组。


你的问题提到退休但没有问题。

Retire 至少与 issue 一样宽(从 Core2 到 Skylake 4 宽,Ice Lake 5 宽)。

Sandybridge / Haswell淘汰 4 个融合域微指令/时钟。Skylake 可以在每个超线程的每个时钟上淘汰 4 个融合域微指令,如果两个逻辑核心都忙,则可以在一个旧的停滞微指令最终完成后更快地释放资源,例如加载缓冲区。在单线程模式下运行时是否可以退出 8/clock 并不是 100% 明确的,我发现了相互矛盾的说法,并且在 Intel 的优化手册中也没有明确的说明。

要真正造成退休瓶颈(但不是问题),即使不是不可能,也是非常困难的。任何持续的流都必须通过发行阶段,这个阶段不比退休更广泛。(性能计数器uops_issued.any表明未分层发生在发布前的某个时间点,因此这无助于我们通过前端堵塞更多的微指令,而不是退休可以处理。除非这是误导;在两个逻辑核心上运行相同的循环相同的物理内核应该具有相同的总体瓶颈,但如果 Skylake 运行得更快,那将告诉我们并行 SMT 退役有帮助。不太可能,但如果有人想排除它,需要检查一下。)


这也是 IACA 报告的吞吐量

IACA 的管道模型似乎很幼稚。我认为它不知道 Sandybridge 的 4 uop 倍数问题效应(例如,6 uop 循环的成本与 8 相同)。IACA 也不知道 Haswell 可以add eax, [rdi+rdx]在整个管道中保持微熔合,因此对未分层的索引 uop 的任何分析都是错误的。

我不会相信 IACA 会做的不仅仅是计算 uops 并对它们将如何分配给端口做出一些疯狂的猜测。


推荐阅读