多个值或范围作为单个指令的延迟意味着什么?

What do multiple values or ranges means as the latency for a single instruction?

我对 https://uops.info/ 上的指令延迟有疑问。

对于某些指令,例如 PCMPEQB(XMM, M128),Skylake 的 table 条目中的延迟列为 [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 还是更高的数字?

为什么 2 个号码 : 分开?

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

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

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

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

Operand 1 (r/w): is the XMM Register
Operand 2 (r): Memory

  • Latency operand 1 → 1: 1
  • Latency operand 2 → 1 (address, base register): ≤8
  • Latency operand 2 → 1 (memory): ≤5

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

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


可变延迟:为什么≤8

存储转发延迟 on SnB family, and address-generation / L1d Load-use latency can be as well ()。请注意,这有一个内存源操作数。 但这就是延迟被列为 ≤ n 的原因 而不是

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

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

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

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

例如store/reload 有一些延迟,但您如何选择将其归咎于存储还是负载? (一个明智的选择是将负载的延迟列为 L1d 负载使用延迟,但是 。他的负载与存储延迟完全是任意的,比如分成两半之类的,导致极低的负载延迟不是加载使用延迟:/)

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

正如@BeeOnRope 评论的那样,uops.info 通常是一个往返时间,显示的延迟是整个周期的值减去任何已知的填充指令,减去 1. 例如,如果您将 GP -> SIMD -> GP 往返计时为 4 个周期(无填充),则这两条指令都将显示为 <= 3。

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


例如,

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

(34.0 似乎很高;也许我误解了什么。输入确实有很多重要的尾数位,而我认为实验 2 正在做 1.0 / 1.0,循环中没有其他任何东西,测量结果为 6 XMM -> XMM 的循环延迟是最佳情况。)

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