assembly - 新的 AVX 指令语法

标签 assembly sse avx

我有一个用一些 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 语法总是更好吗?

最佳答案

Is it always better to use new AVX syntax if possible?



我认为第一个问题是询问文件夹指令是否比非文件夹指令对更好。折叠需要一对这样的读取和修改指令
vmovdqa %xmm0, %xmm2
vpunpckhbw %xmm2, %xmm1, %xmm1

并将它们“折叠”成一个组合指令
vpunpckhbw  %xmm0, %xmm1, %xmm2

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

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

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

请注意,一般来说,使用 vex 编码的指令应该仍然更好。但是我认为大多数编译器(如果不是全部)现在都假设折叠总是更好,因此除了使用汇编(甚至不能使用内在函数)或在某些情况下告诉编译器不要使用 AVX 编译之外,您无法控制折叠。

关于assembly - 新的 AVX 指令语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38187690/

相关文章:

C代码循环性能

c - SSE:使用_mm_add_epi32看不到加速

一个目标文件中的代码对齐会影响另一个目标文件中函数的性能

assembly - SIMD minmag 和 maxmag

c++ 通过引用和指针传递参数

从 bootloader 调用 32 位或 64 位程序

c++ - 什么会导致 _mm_setzero_si128() 变为 SIGSEGV?

c++ - gcc 函数属性 - 如何使用它们?

c++ - 将 Ceres 与带有 sse/avx 的库一起使用时出错

assembly - "AND AL,0xFF"的目的是什么?