首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC++

SSE 指令集介紹與 C/C++ 內建函式實戰應用

     編輯:VC++

SSE 簡介

SSE (Streaming SIMD Extensions) 為 Intel PIII 引入、現主流 x86 CPU (P4、Core、Athlon 等) 均支援的 128-bit SIMD 指令集。SIMD (Single Instruction Multiple Data) 讓單一指令並行處理 4 個 32-bit 浮點數 (float[4]),理論峰值效能提升 4 倍。SSE2 (P4+) 再增 64-bit 浮點/整數支援,本文聚焦 SSE。

資料類型與對齊要求


// 核心類型定義於 
typedef struct __declspec(align(16)) __m128 {
    float m128_f32[4];
} __m128;

關鍵限制:__m128 變數與記憶體操作數**必須 16-byte 對齊**,否則觸發 General Protection Fault。靜態陣列用 __declspec(align(16)),動態分配用 _aligned_malloc。

常用內建函式速查 (編譯器內建,非函式呼叫開銷)

功能內建函式說明
設定全 1 值_mm_set_ps1(float)四元素皆設為該值
設定四不同值_mm_set_ps(z,y,x,w)逆序對應 m128_f32[0..3]
清零_mm_setzero_ps()高效清零
載入 (對齊)_mm_load_ps(float*)要求 16-byte 對齊
載入 (非對齊)_mm_loadu_ps(float*)無對齊要求,稍慢
儲存 (對齊)_mm_store_ps(float*, __m128)
加法_mm_add_ps(a,b)四元素並行相加
乘法_mm_mul_ps(a,b)四元素並行相乘
加法乘法融合_mm_add_ps(_mm_mul_ps(a,b), c)手工 FMA
比較_mm_cmpeq_ps, _mm_cmplt_ps...回傳遮罩 (0xFFFFFFFF/0)
水平加總_mm_hadd_ps (SSE3)SSE 需手工 shuffle+add

實戰範例:陣列標量乘法加速


#include 
#include 
#include 

class CTimer {
    LARGE_INTEGER freq, start;
public:
    CTimer() { QueryPerformanceFrequency(&freq); Reset(); }
    void Reset() { QueryPerformanceCounter(&start); }
    double Elapsed() {
        LARGE_INTEGER now; QueryPerformanceCounter(&now);
        return double(now.QuadPart - start.QuadPart) / freq.QuadPart;
    }
};

void Scale_SSE(float* pArray, DWORD count, float scale)
{
    DWORD groups = count / 4;
    __m128 vScale = _mm_set_ps1(scale);
    for (DWORD i = 0; i < groups; ++i)
    {
        __m128* p = (__m128*)(pArray + i * 4);
        *p = _mm_mul_ps(*p, vScale); // 載入、乘、存回
    }
    // 處理餘數 (略)
}

void Scale_Scalar(float* pArray, DWORD count, float scale)
{
    for (DWORD i = 0; i < count; ++i) pArray[i] *= scale;
}

#define N 10000
#define LOOPS 100000

int main()
{
    __declspec(align(16)) float arr[N] = {0};
    CTimer t;

    t.Reset();
    for (int i=0; i

效能分析與避坑指南

  • 記憶體頻寬是瓶頸:SSE 計算極快,實際加速受限於載入/儲存頻寬。連續記憶體存取 (如陣列處理) 效果最佳。
  • 對齊是硬性要求:未對齊存取會崩潰。用 _mm_loadu_ps 可避免崩潰但效能下降。
  • 餘數處理:陣列長度非 4 倍數時,尾部需標量處理或掩碼合併。
  • 編譯器自動向量化:現代編譯器 (MSVC /O2, GCC -O3 -march=native) 常能自動將簡單迴圈向量化,手寫內建函式適用於複雜邏輯或編譯器無法優化的情況。
  • SSE2/AVX 遷移:SSE2 支援 __m128d (double[2])、__m128i (整數),AVX (256-bit) 進一步擴展,語法高度相似。

結語

SSE 為多媒體、科學計算、圖像處理等資料密集型應用提供極佳加速。善用 xmmintrin.h 內建函式,配合對齊記憶體配置,可在 C/C++ 直接發揮 SIMD 潛能,無需撰寫組合語言。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved