die*_*etr 2 optimization assembly sse simd intrinsics
许多SSE指令允许源操作数是16字节对齐的存储器地址.例如,各种(非)包装说明.PUNCKLBW有以下签名:
PUNPCKLBW xmm1,xmm2/m128
现在,对于内在函数来说,这似乎是不可能的.看起来必须使用_mm_load*intrinsics来读取内存中的任何内容.这是PUNPCKLBW的内在特征:
__m128i _mm_unpacklo_epi8(__ m128i a,__ m128i b);
(据我所知,__ m128i类型总是指XMM寄存器.)
现在,这是为什么?这是相当悲伤,因为我通过直接寻址内存看到了一些优化潜力......
内在函数相对直接对应于实际指令,但编译器没有义务发出相应的指令.在操作的存储器形式中优化操作之后的操作(即使在用内在函数编写时)是由所有可敬的编译器执行的常见优化,这样做是有利的.
TLDR:在内在函数中编写加载和操作,并让编译器对其进行优化.
编辑:琐碎的例子:
#include <emmintrin.h>
__m128i foo(__m128i *addr) {
__m128i a = _mm_load_si128(addr);
__m128i b = _mm_load_si128(addr + 1);
return _mm_unpacklo_epi8(a, b);
}
Run Code Online (Sandbox Code Playgroud)
编译gcc -Os -fomit-frame-pointer给出:
_foo:
movdqa (%rdi), %xmm0
punpcklbw 16(%rdi), %xmm0
retq
Run Code Online (Sandbox Code Playgroud)
看到?优化器将对其进行排序.