新的AVX指令语法

时间:2016-07-04 15:03:25

标签: assembly sse avx

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

AVX:

vpunpckhbw  %xmm0, %xmm1, %xmm2 

SSSE3:

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

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

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

如果可能,最好使用新的AVX语法吗?

1 个答案:

答案 0 :(得分:5)

  

如果可能,最好使用新的AVX语法吗?

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

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

和"折叠"将它们合并为一个组合指令

vpunpckhbw  %xmm0, %xmm1, %xmm2

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

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

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

请注意,通常情况下,使用vex编码指令仍然会更好。但我认为大多数编译器,如果不是全部,现在假设折叠总是更好,所以你无法控制折叠,除了汇编(甚至没有内在函数),或者在某些情况下通过告诉编译器不用AVX编译。