_mm_load_si128和_mm_loadu_si128解析
一 基本功能
两者均为Intel SIMD指令集(SSE/AVX)中的函数,用于将128位数据从内存加载到SSE寄存器(如XMM0-XMM15),以便进行并行运算(如处理4个int32、8个int16等)。
二 关键区别
1)_mm_load_si128
要求内存地址必须16字节对齐(即地址是16的倍数)。若地址未对齐,调用此函数会导致未定义行为(程序崩溃或数据错误)。
语法:__m128i _mm_load_si128(const __m128i *mem_addr);
2)_mm_loadu_si128
允许内存地址未对齐(无需是16的倍数)。
牺牲少量性能换取灵活性,适用于无法保证对齐的场景。
语法:__m128i _mm_loadu_si128(const __m128i *mem_addr);
三 性能差异
对齐加载(_mm_load_si128)通常更快,因为对齐内存访问可直接通过单条指令完成,减少总线周期。未对齐加载(_mm_loadu_si128)可能需要额外操作(如合并多个内存块),现代CPU已优化此操作,但仍有轻微开销。
四 使用示例
#include <emmintrin.h>
// 对齐内存
alignas(16) int32_t aligned_arr[4] = {1, 2, 3, 4};
int32_t unaligned_arr[4] = {5, 6, 7, 8};
// 对齐加载
__m128i vec_aligned = _mm_load_si128((__m128i*)aligned_arr);
// 未对齐加载
__m128i vec_unaligned = _mm_loadu_si128((__m128i*)unaligned_arr);
五 注意事项
1)内存对齐声明
对齐数据需通过编译器指令显式声明(如alignas(16)或__attribute__((aligned(16))))。
2)错误使用后果
错误地对未对齐数据使用_mm_load_si128会导致段错误(Segmentation Fault)。
六 相关函数
1)存储操作
_mm_store_si128(对齐存储);_mm_storeu_si128(未对齐存储)。
2)其他数据类型
_mm_load_pd(加载双精度浮点数);_mm_load_ps(加载单精度浮点数)。
七 总结
需要内存对齐且能保证对齐时_mm_load_si128(更高效)。无法保证对齐或处理外部数据时 _mm_loadu_si128(更安全)。