SSE2内在函数:直接访问内存

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寄存器.)

现在,这是为什么?这是相当悲伤,因为我通过直接寻址内存看到了一些优化潜力......

Ste*_*non 6

内在函数相对直接对应于实际指令,但编译器没有义务发出相应的指令.在操作的存储器形式中优化操作之后的操作(即使在用内在函数编写时)是由所有可敬的编译器执行的常见优化,这样做是有利的.

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)

看到?优化器将对其进行排序.