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
_mm_loadu_ps 可避免崩潰但效能下降。__m128d (double[2])、__m128i (整數),AVX (256-bit) 進一步擴展,語法高度相似。SSE 為多媒體、科學計算、圖像處理等資料密集型應用提供極佳加速。善用 xmmintrin.h 內建函式,配合對齊記憶體配置,可在 C/C++ 直接發揮 SIMD 潛能,無需撰寫組合語言。