SSE函数
SSE(Streaming SIMD Extensions)函数,是Intel推出的一套SIMD指令集扩展。
SSE是Intel在1999年推出的SIMD(单指令多数据)指令集,允许在单个指令中同时处理多个数据元素,显著提升多媒体和科学计算应用的性能。
基本数据类型
#include <xmmintrin.h>  // SSE
#include <emmintrin.h>  // SSE2
// 主要数据类型:
__m128     // 4个单精度浮点数
__m128d    // 2个双精度浮点数  
__m128i    // 整数(16×8位, 8×16位, 4×32位, 2×64位)
常用SSE函数分类
- 数据加载和存储
- 算术运算
- 比较运算
- 逻辑运算
- 位移运算
// 加载操作
__m128 _mm_load_ps(float* p);     // 对齐加载
__m128 _mm_loadu_ps(float* p);    // 未对齐加载
__m128 _mm_set_ps(float z, float y, float x, float w); // 设置值
// 存储操作
void _mm_store_ps(float* p, __m128 a);    // 对齐存储
void _mm_storeu_ps(float* p, __m128 a);   // 未对齐存储
// 算术运算
__m128 _mm_add_ps(__m128 a, __m128 b);    // a + b
__m128 _mm_add_ss(__m128 a, __m128 b);    // 仅低32位相加
__m128 _mm_sub_ps(__m128 a, __m128 b);    // a - b
__m128 _mm_mul_ps(__m128 a, __m128 b);    // a * b
__m128 _mm_div_ps(__m128 a, __m128 b);    // a / b
__m128 _mm_sqrt_ps(__m128 a);             // sqrt(a)
// 比较运算
__m128 _mm_cmpeq_ps(__m128 a, __m128 b);  // a == b
__m128 _mm_cmpgt_ps(__m128 a, __m128 b);  // a > b
__m128 _mm_cmplt_ps(__m128 a, __m128 b);  // a < b
__m128 _mm_cmpge_ps(__m128 a, __m128 b);  // a >= b
__m128 _mm_cmple_ps(__m128 a, __m128 b);  // a <= b
// 逻辑运算
__m128 _mm_and_ps(__m128 a, __m128 b);    // 按位与
__m128 _mm_or_ps(__m128 a, __m128 b);     // 按位或  
__m128 _mm_xor_ps(__m128 a, __m128 b);    // 按位异或
__m128 _mm_andnot_ps(__m128 a, __m128 b); // 按位与非
// 移位和混洗
__m128 _mm_shuffle_ps(__m128 a, __m128 b, int imm8); // 混洗
__m128i _mm_slli_epi32(__m128i a, int count);        // 左移
1. 数据加载和存储
1.1. _mm_load_ps
_mm_load_ps 用于从内存中加载4个单精度浮点数到SSE寄存器中,要求内存地址必须16字节对齐。
__m128 _mm_load_ps(float const* mem_addr);
#include <xmmintrin.h>
#include <stdio.h>
int main() {
    // 16字节对齐的数组(C11对齐语法)
    float aligned_array[4] __attribute__((aligned(16))) = {1.0f, 2.0f, 3.0f, 4.0f};
    // 使用_mm_load_ps加载数据
    __m128 vec = _mm_load_ps(aligned_array);
    // 将结果存回另一个对齐数组
    float result[4] __attribute__((aligned(16)));
    _mm_store_ps(result, vec);
    printf("Loaded values: %.1f, %.1f, %.1f, %.1f\n", 
           result[0], result[1], result[2], result[3]);
    return 0;
}