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

ELH*_*ERS 2 performance x86 assembly cpu-architecture micro-optimization

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

对于某些指令,例如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
Run Code Online (Sandbox Code Playgroud)

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

或者例如,

PMOVMSKB (R32, XMM)
Run Code Online (Sandbox Code Playgroud)

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

Pet*_*des 6

为什么是两个数字,:分开?

该指令有 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 测试真正闪耀的地方,特别是对于像mul或 之类的多 uop 指令shr reg, cl。例如,对于移位,从 reg 或移位计数到输出的延迟仅为 1 个周期;额外的 uops 仅用于 FLAGS 合并。


可变延迟:为什么?8

存储转发延迟在 SnB 系列上可变的,地址生成/L1d 负载使用延迟也可以(当 base+offset 与 base 位于不同的页面时是否有惩罚?)。注意它有一个内存源操作数。 但这不是延迟被列为? n.

?n延迟值是一个上限,我认为。它并不意味着,从操作的等待时间可能会低至1。

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

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

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

例如,存储/重新加载有一些延迟,但是您如何选择将哪个归咎于存储与加载?(一个明智的选择是将负载的延迟列为 L1d 负载使用延迟,但不幸的是,这不是Agner Fog 选择的。他的负载与存储延迟完全是任意的,比如分成两半之类的,导致负载低得离谱不是负载使用延迟的延迟:/)

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

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

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


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

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

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