【问题标题】:New AVX-instructions syntax新的 AVX 指令语法
【发布时间】:2016-11-06 08:40:27
【问题描述】:

我有一个用一些 intel-intrinsincs 编写的 C 代码。在我先用 avx 然后用 ssse3 标志编译它之后,我得到了两个完全不同的汇编代码。例如:

AVX:

vpunpckhbw  %xmm0, %xmm1, %xmm2 

SSSE3:

movdqa %xmm0, %xmm2
punpckhbw %xmm1, %xmm2

很明显,vpunpckhbw 只是 punpckhbw,但使用的是 avx 三操作数语法。但是第一条指令的延迟和吞吐量是否等于最后一条指令的延迟和吞吐量的总和? 还是答案取决于我使用的架构?顺便说一下,它是 IntelCore i5-6500。

我试图在 Agner Fog 的说明表中搜索答案,但找不到答案。英特尔规范也没有帮助(但是,我可能只是错过了我需要的那个)。

如果可能,使用新的 AVX 语法总是更好吗?

【问题讨论】:

  • 有些日子,你不只是渴望mov al,8的旧时光 :-)
  • @Neil 哦,是的,我渴望 rep movsb 被认为是 SIMD 的日子。
  • 如果您需要支持 AVX,那么您的问题的答案很可能没有实际意义,因为在旧类型(非 VEX)SSE 指令和 VEX 编码 SSE 之间切换会导致高性能损失/AVX 指令在运行时。因此,它是“全有或全无”。
  • 您的 CPU 每个时钟周期只能推送 4 个微融合微操作。在 AVX 情况下,负载可以微熔。在 SSE 的情况下,它不能。这可能意味着在一个紧密的循环中,SSE 案例需要五个微操作,而 AVX 案例只需要四个融合微操作。这可能会对性能产生很大影响。请参阅this 了解更多详情或等待 Peter Cordes 回复更多更好的细节。
  • 我见过一些情况,使用 -mavx 重新编译遗留 SSE 代码会带来适度的性能提升,这可能是由于非破坏性 VEX SSE 指令减少了需要执行的指令数同样的工作。

标签: assembly sse avx


【解决方案1】:

如果可能,使用新的 AVX 语法总是更好吗?

我认为第一个问题是询问文件夹指令是否优于非文件夹指令对。折叠需要一对这样的读取和修改指令

vmovdqa %xmm0, %xmm2
vpunpckhbw %xmm2, %xmm1, %xmm1

并将它们“折叠”成一个组合指令

vpunpckhbw  %xmm0, %xmm1, %xmm2

自从 Ivy Bridge 以来,寄存器到寄存器移动指令可以具有零延迟并且可以使用零执行端口。但是,展开的指令对仍然算作前端的两条指令,因此会影响整体吞吐量。然而,折叠指令仅计为前端中的一条指令,它降低了前端的压力而没有任何副作用。这可以提高整体吞吐量。

然而,为了让内存记录移动,折叠 can 可能会产生副作用(目前有 some debate 关于此),即使它降低了前端的压力。原因是从前端的角度来看,乱序引擎只看到一个折叠指令(假设this answer 是正确的),如果由于某种原因重新排序内存读取操作会更优化(因为它确实需要执行端口并且有延迟)独立于折叠指令中的其他操作,乱序引擎将无法利用这一点。我第一次观察到这个here

对于您的特定操作,AVX 语法总是更好,因为它将寄存器折叠到寄存器移动。但是,如果您有内存来注册移动文件夹,在某些情况下,AVX 指令的性能可能会比展开的 SSE 指令对更差。


请注意,一般来说,使用 vex 编码的指令应该会更好。但我认为大多数编译器,如果不是全部的话,现在都认为折叠总是更好,所以你无法控制折叠,除非使用汇编(甚至不是内在函数),或者在某些情况下告诉编译器不要使用 AVX 编译。

【讨论】:

  • 是的,最好使用 VEX 编码的非破坏性目标功能来避免 reg-reg mov 指令。不过,我不认为“折叠”是正确的词:认为它实际上将 movdqa 指令与 ALU 操作结合起来是错误的心理图景,IMO。这不像将负载折叠到 ALU 指令中,因为寄存器重命名意味着 punpckhbw %xmm1, %xmm2 的结果已经被写入与任一输入不同的物理寄存器。对于术语,“mov 消除”也已经采用:/
  • 不确定您的意思是“在 Sandy Bridge 处理器上...... [3 操作数] 指令的性能可能更差”,即使在 reg-reg 情况下也是如此。那是错误的,除非您要摆脱的movdqa 占用了适当的空间来稍后对齐某些内容。由于movqda 仍然在 SnB(不是 IvB 或更高版本)上使用执行端口,因此避免它的 VEX 编码是一个更大的胜利。
  • @PeterCordes,您对我对 Sandy Bridge 的评论完全正确。我看到你对术语的看法,因为折叠意味着适用于内存读/写的微操作融合,但我认为通过类比折叠是好的。使用 reg reg move 进行折叠与 mem reg move 相同,只是它不消耗微操作并且不使用端口。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-15
  • 2016-03-16
  • 1970-01-01
  • 2014-08-10
相关资源
最近更新 更多