【问题标题】:Bottleneck when using indexed addressing modes使用索引寻址模式时的瓶颈
【发布时间】:2020-11-26 19:31:41
【问题描述】:

我在 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-64 intel cpu-architecture micro-optimization addressing-mode


    【解决方案1】:

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

    假设:可能由于未分层而产生的两个 uops 都必须属于同一个问题组,因此 unlaminated; nop 重复只能实现每个时钟 3 个融合域 uops 的前端吞吐量.

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


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

    也许times 2 nop; unlaminatetimes 3 nop 也可能是一个有趣的测试,看看未层压的uop 是否会自行发出问题,或者在它从问题组中的任何位置延迟后能否可靠地再获得2 个NOP。从您的背靠背cmp-unlaminate 测试来看,我预计我们仍然会看到大部分完整的 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 并对它们将如何分配给端口做出一些疯狂的猜测。

    【讨论】:

    • 根据en.wikichip.org/wiki/intel/microarchitectures/…,在 Skylake 上,retire 是每个周期 4 µops,“分配队列传递”是每个周期 6 µops。
    • cmp dword ptr [rip+0x8], 1; nop 达到 0.75c(如果微操作来自 DSB)。
    • nop;nop;cmp rbx,QWORD PTR [r14+rax]; 达到 1c,nop;nop;nop;cmp rbx,QWORD PTR [r14+rax]; 达到 1.33c。
    • @AndreasAbel:SKL 的 uop 缓存每时钟最多可以向 IDQ 的远端提供 6 uop。发行阶段肯定只有 4 宽,在 SMT 线程之间竞争共享。 (与每个 SMT 线程可以独立退休的退休不同。但对于这种持续吞吐量的情况,退休宽度不是瓶颈,即使它只有 4 宽,除非它也有来自 unlamination 的奇怪影响)。 wikichip 上的那一段似乎具有误导性。英特尔的优化手册确认 Skylake 是 4 宽的,例如Ice Lake 将分配范围从 Core 2 以来的 4 个扩大到 5 个。
    • 在 Haswell 上,一个包含 55 个 cmp rbx, [r14+rax] 指令的循环从 LSD 运行。因此,当 uops 离开 IDQ 时/之后,似乎会发生脱层。
    猜你喜欢
    • 2018-05-31
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    • 1970-01-01
    • 1970-01-01
    • 2022-08-22
    • 2021-08-24
    • 1970-01-01
    相关资源
    最近更新 更多