【问题标题】:Choosing SSE instruction execution domains in mixed contexts在混合环境中选择 SSE 指令执行域
【发布时间】:2015-02-22 17:12:29
【问题描述】:

我正在使用一些 SSE 汇编代码,其中我没有足够的 xmm 寄存器来同时将所有临时结果和有用的常量保存在寄存器中。

作为一种解决方法,对于一些具有相同分量的常量向量,我将几个向量“压缩”到一个xmm 寄存器中,下面是xmm14。我使用pshufd 指令来解压我需要的常量向量。这条指令有一点延迟,但由于它需要一个源寄存器和一个目标寄存器,否则非常方便:

…
Lfour_15_9:
    .long 4
    .long 1549556828
    .long 909522486
    .long 0
…
    movdqa  Lfour_15_9(%rip), %xmm14
…
    pshufd  $0, %xmm14, %xmm4
    paddd   %xmm4, %xmm3
…
    pshufd  $0b10101010, %xmm14, %xmm5
…
    pshufd  $0b10101010, %xmm14, %xmm5
…
    pshufd  $0b01010101, %xmm14, %xmm5
    xorps   %xmm5, %xmm2    
    movaps  %xmm5, 112(%rax)

以上代码采用 gas/AT&T 语法,我的目标是从 Core 2 到 Westmere 的 Intel 处理器,这些处理器提供高达 SSSE3 的指令。

Agner Fog's manuals 之一指出,对于某些用途,使用具有错误“类型”的向量指令可能是有利的。例如,memcpy 使用 movaps 指令编写是有利的,即使要移动的数据不是浮点数,因为 movapsmovdqa 短,在更多处理器上可用,并且因为它不计算数据,关于次常态的通常警告都不适用。也给出了相同的建议来改变单词(我之前链接到的手册中的第 13.2 和 13.3 节)。

我的情况有点特殊,因为我打算重构常量向量,如果需要,一些可以仅与单精度“类型”指令一起使用:这些将仅在movapsshufps 中涉及, xorps 计算。一些常量向量必须参与只能用整数类型指令完成的计算:paddd(因此我可以根据需要使用movdqapshufdpxor指令来保持整数执行域)。

这个问题的一般版本是:考虑到我的目标是 Core 2 和 Westmere 之间的英特尔处理器,我应该分别使用什么类型的指令从内存(重新)加载 xmm14,将其解压缩到寄存器那将只看到单精度计算,将其解压缩到一个寄存器,该寄存器将看到一些单精度指令无法完成的计算,以及后一种情况下可以用单精度指令完成的那些操作?


编辑: harold 在评论中回答了以下问题的一部分。


还有一个包含在一般问题中的更具体的子问题:当我用浮点指令随机替换一些整数执行域指令(例如,movdqa 指令由movaps 指令替换时,是否有人解释了原因? ),函数可以计算错误吗?我预计唯一的后果是执行延迟,而不是错误的结果。

例如,如果在上面我仅将pshufd $0, %xmm14, %xmm4 指令更改为shufps 指令,则计算将完全错误(xmm4 是稍后涉及paddd 的寄存器)。更改其他指令而不是那个会导致其他类型的错误。

【问题讨论】:

  • 你不能把pshufd $0, %xmm14, %xmm4写成shufps。最低的两个花车将来自目的地。
  • @harold 哦。我认为这回答了关于正确性的问题。现在这个问题感觉很傻(我只是问,因为我认为至少正确性方面很有趣)。
  • movdqa -> movaps 更改是否也破坏了某些东西?那会更有趣,因为它真的不应该
  • @harold 不,我没有看到它破坏任何东西。我真的很困惑,因为 pshufd -> shufps 更改有时会起作用(在其他情况下源和目标相同)。

标签: assembly vector sse


【解决方案1】:

对于xor 之类的东西,更喜欢整数域指令。在 Intel CPU 上,只有一个执行端口可以处理 FP 域逻辑(XORPS 等),但大多数执行单元(在 SnB 到 Haswell:p015,但不是 Haswell 的端口 6)可以处理向量整数逻辑指令( PAND/POR/PXOR)。

根据 Agner Fog 的测试,如果需要将 FP 域指令的结果作为向量整数域指令的输入,有时会花费额外 1 个周期的延迟。 (请参阅微架构文档)。这适用于 AMD 和英特尔。这仅在指令位于关键路径上时才重要。 (循环中最长的深度链)。

正确性不是问题,除非您发现指令的非正交性让您绊倒。 shufpspshufd 做的事情不同。我认为vpermilps ymm, ymm, imm 确实与pshufd 做同样的事情,而且似乎只是被引入,因此您可以将随机播放与内存加载结合起来。 (否则,您可以使用 AVX 版本的 shufps 与两个源具有相同的寄存器,并获得相同的行为)。

IDK 如果有人彻底测试了使用较短指令编码...ps 版本的事物没有额外延迟的所有情况。不过,SnB 和更高版本的 Intel CPU 中的 uop 缓存使得内部循环的问题不再那么严重。 (指令解码只是第一次循环的瓶颈。)

编辑:除了 uop-cacheline 边界,如果您的代码可以维持完整的 4 uop / 周期,这可能是瓶颈。如果有任何工具可以帮助对齐 x86 指令以使 uop 缓存行保持 4 uop 的倍数,请 IDK。

【讨论】:

  • 更新:Skylake 在任何端口上运行 FP 逻辑,绕过转发延迟取决于实际选择的端口。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-07
  • 1970-01-01
  • 2011-06-27
相关资源
最近更新 更多