新的 AVX 指令语法

New AVX-instructions syntax

我有一个用一些英特尔内部函数编写的 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

和"folds"它们合并为一个指令

vpunpckhbw  %xmm0, %xmm1, %xmm2

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

但是,对于内存注册移动折叠 can 可能有副作用(目前有 some debate about this) even if it lowers pressure on the front-end. The reason is that the out-of-order engine from the front-ends point of view only sees a folded instruction (assuming this answer is correct) and if for some reason it would be more optimal to reorder the memory read operation (since it does require execution ports and has latency) independently from the other operations in the folded instruction the out-of-order engine won't be able to take advantage of this. I observed this for the first time here.

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


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