新的avx指令语法



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

AVX:

vpunpckhbw  %xmm0, %xmm1, %xmm2 

SSSE3:

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

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

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

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

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

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

并将它们"折叠"成一条合并的指令

vpunpckhbw  %xmm0, %xmm1, %xmm2

由于Ivy Bridge一个寄存器到寄存器的移动指令可以有零延迟并且可以使用零执行端口。但是,未展开的指令对在前端仍然算作两条指令,因此会影响总体吞吐量。然而,折叠后的指令在前端只算作一条指令,这降低了前端的压力,没有任何副作用。这可以提高总体吞吐量。

然而,对于内存寄存器移动,折叠可以可能有副作用(目前对此有一些争论),即使它降低了前端的压力。原因是,从前端的角度来看,乱序引擎只看到一个折叠的指令(假设这个答案是正确的),如果出于某种原因,独立于折叠指令中的其他操作重新排序内存读取操作(因为它确实需要执行端口并且有延迟)会更优,那么乱序引擎将无法利用这一点。我在这里第一次观察到这一点。

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


请注意,一般来说,使用向量编码的指令应该更好。但我认为大多数编译器,如果不是全部,现在假设折叠总是更好,所以你没有办法控制折叠,除了汇编(甚至不是与内在的)或在某些情况下告诉编译器不要编译AVX。

最新更新