_mm_loadu_ps
我认为使用甚至在“Intel Nehalem 及更高版本(包括 Silvermont 及更高版本)和 AMD Bulldozer 及更高版本”之间存在细微差别,_mm_load_ps
这可能会对性能产生影响。
将加载和其他操作(例如乘法)折叠到一条指令中的操作只能使用 而load
不是loadu
内在函数来完成,除非您在启用 AVX 的情况下进行编译以允许未对齐的内存操作数。
考虑以下代码
#include <x86intrin.h>
__m128 foo(float *x, float *y) {
__m128 vx = _mm_loadu_ps(x);
__m128 vy = _mm_loadu_ps(y);
return vx*vy;
}
这将转换为
movups xmm0, XMMWORD PTR [rdi]
movups xmm1, XMMWORD PTR [rsi]
mulps xmm0, xmm1
但是,如果使用对齐的负载内在函数 ( _mm_load_ps
),它会被编译为
movaps xmm0, XMMWORD PTR [rdi]
mulps xmm0, XMMWORD PTR [rsi]
这节省了一条指令。但是,如果编译器可以使用 VEX 编码加载,那么 unaligned 也只有两条指令。
vmovups xmm0, XMMWORD PTR [rsi]
vmulps xmm0, xmm0, XMMWORD PTR [rdi]
movaps
因此,尽管在使用指令和movups
Intel Nehalem 及更高版本或 Silvermont 及更高版本或 AMD Bulldozer 及更高版本时性能没有差异,但对齐访问。
但是在没有启用 AVX 的情况下编译时使用和内在函数时的性能可能会有所不同,在编译器的权衡不是vs.的情况下,它介于负载之间或将负载折叠到 ALU 指令中。(当向量仅用作一件事的输入时会发生这种情况,否则编译器将使用负载将结果放入寄存器以供重用。)_mm_loadu_ps
_mm_load_ps
movaps
movups
movups
mov*