【问题标题】:What do multiple values or ranges means as the latency for a single instruction?多个值或范围作为单个指令的延迟意味着什么?
【发布时间】:2020-07-09 18:39:03
【问题描述】:

我对@9​​87654321@ 的指令延迟有疑问。

对于像 PCMPEQB(XMM, M128) 这样的一些指令,Skylake 表条目中的延迟被列为 [1;≤8]

我对延迟了解一点,但我知道它只是一个数字!!!例如,1 或 2 或 3 或 ... 但是这是什么[1;≤8] !!!???这意味着延迟取决于内存,它在 1 到 8 之间?

如果是真的,什么时候是 1.. 什么时候是 3,等等?

例如,这个延迟是多少:

pcmpeqb xmm0, xword [.my_aligned_data]

....
....

align 16
.my_aligned_data db 5,6,7,2,5,6,7,2,5,6,7,2,5,6,7,2

这里pcmpeqb xmm0, xword [.my_aligned_data] 的确切延迟值是多少???

例如,

PMOVMSKB (R32, XMM)

这条指令的延迟是 (≤3) !!!什么意思 ?!这是否意味着延迟在 1 到 3 之间?如果是,则此指令仅适用于寄存器!!!那么当时它是1还是更高的数字?

【问题讨论】:

    标签: performance assembly x86 cpu-architecture micro-optimization


    【解决方案1】:

    为什么 2 个数字,: 分开?

    该指令有 2 个输入和 2 个 uops(未融合域),因此两个输入不需要同时。例如加载需要内存地址,但在加载准备好之前不需要向量寄存器输入。

    这就是延迟值中有 2 个单独字段的原因。

    单击https://uops.info/ 中的延迟数字链接,了解哪个操作数对哪个结果具有哪个延迟的细分。

    https://www.uops.info/html-lat/SKL/PCMPEQB_XMM_M128-Measurements.html 将其分解为针对 Skylake 的特定指令,该指令具有 2 个输入和一个输出(与其中一个输入在同一操作数中,因为这是非 VEX 版本。(有趣的事实:它可以保持即使在 HSW 和更高版本上使用索引寻址模式,uop 也进行了微融合,这与 VEX 版本不同)):

    操作数 1 (r/w):是 XMM 寄存器
    操作数 2 (r):内存

    • 延迟操作数 1 → 1:1
    • 延迟操作数 2 → 1(地址、基址寄存器):≤8
    • 延迟操作数 2 → 1(内存):≤5

    下面是用于测试该指令的特定指令序列。

    与任何其他测试结果或发布的数字相比,这个详细的细分是 uops.info 测试真正闪耀的地方,尤其是对于像 mulshr reg, cl 这样的多微指令指令。例如对于班次,从 reg 或班次计数到输出的延迟仅为 1 个周期;额外的微指令仅用于 FLAGS 合并。


    可变延迟:为什么≤8

    SnB 系列上的存储转发延迟 is variable,地址生成/L1d 加载使用延迟也可以 (Is there a penalty when base+offset is in a different page than the base?)。请注意,这有一个内存源操作数。 但这不是延迟被列为≤ n的原因。

    ≤n 延迟值是一个上限,我认为。它确实意味着该操作数的延迟可能低至 1。

    我认为他们只在无法准确测试确定下限的情况下才给出上限。

    PMOVMSKB (R32, XMM) 这样在与输入不同的域中产生输出的指令很难确定。您需要使用其他指令将输出反馈到输入中以创建一个循环携带的依赖链,并且很难设计实验来将责任归咎于链的一部分与另一部分。

    但与InstLatx64 不同的是,https://uops.info/ 背后的人并没有在这些情况下放弃。他们的测试总比没有好!

    例如存储/重新加载有一些延迟,但是您如何选择将哪一个归咎于存储与负载? (一个明智的选择是将负载的延迟列为 L1d 负载使用延迟,但 unfortunately that's not what Agner Fog chose。他的加载与存储延迟是完全任意的,例如分成两半或其他东西,导致负载延迟极低t 负载使用延迟:/)

    有多种方法可以将整数 reg 中的数据作为 pmovmskb 的输入依赖项返回 XMM reg:ALU 通过 movdpinsrb/w/d/q 或加载。或者在 AVX512 CPU 上,通过kmov 然后使用屏蔽指令。这些都不是简单的,您不能假设 SIMD 加载的加载使用延迟与整数加载相同。 (我们知道存储转发延迟更高。)

    作为@BeeOnRope cmets,uops.info 通常计算往返时间,显示的延迟是整个周期的值,减去任何已知的填充指令,减 1例如,如果您以 4 个周期(无填充)对 GP -> SIMD -> GP 往返计时,则这两条指令都将显示为

    当获得每个指令的上限时,您大概可以假设任何指令至少有 1 个周期延迟。例如对于pmovmskb -> movd 链,您可以假设movd 至少有1 个延迟周期,因此pmovmskb 延迟最多是往返延迟减去1。但实际上它可能更少。


    https://www.uops.info/html-lat/SKL/DIVPD_XMM_M128-Measurements.html 例如为不同的实验显示不同的“链延迟”。例如对于运行 divpd 并使用 ORPD 和 ANDPD 重复创建具有相同股息的 dep 链的1 -> 1 测试之一,uops.info 列出了 dep 链中那些额外指令的已知延迟。它将其列为链延迟:≥10。 (从理论上讲,如果资源冲突或其他一些影响使得它并不总是在 divpd 输出准备好后的 10 个周期内产生结果。这些实验的目的是捕捉我们可能没有预料到的奇怪影响。)所以给定“核心周期:44.0”减去至少 10 的链延迟,我们可以说divpd 延迟最多为 34,其余的 dep 链占其他 10(但可能更多)。

    (34.0 似乎很高;也许我误解了某些东西。输入确实有很多重要的尾数位,而我认为实验 2 正在做1.0 / 1.0,循环中没有其他内容,测量来自 XMM 的 6 个周期延迟-> XMM 是最好的情况。)

    请注意,我在这里只讨论 xmm -> xmm 的情况,而不是他们将 XMM 输出作为地址或内存内容的依赖项反馈的更复杂的测试。

    【讨论】:

    • 减 1。最后 1 来自假设每条指令至少需要一个周期,我猜。因此,如果您以 4 个周期(无填充)对 GP -> SIMD -> GP 往返计时,则两条指令都将显示为
    • 我不同意“在大多数情况下,上限可能是确切的延迟;依赖链可能是我们所期望的。”部分,除非我误解了。我不认为这通常是确切的延迟,而且大多数情况下至少有一半是错误的。鉴于我的 4 周期往返示例,两条指令的两个
    • @BeeOnRope:谢谢,我没有详细查看他们的延迟上限数字或他们如何计时。修正并复制了您的一些措辞。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    相关资源
    最近更新 更多