SSE

SSE（Streaming SIMD Extensions）是英特爾在 AMD 的 3D Now! 釋出一年之後，在其計算機晶片 Pentium III 中引入的指令集，是繼 MMX 的擴充指令集。SSE 指令集提供了 70 條新指令。AMD 後來在 Athlon XP 中加入了對這個新指令集的支援。

SSE 的暫存器

SSE 加入新的 8 個 128 位元暫存器（XMM0～XMM7）。而 AMD 發表的 x86-64 延伸架構（又稱 AMD64）再加入額外 8 個暫存器。除此之外還有一個新的 32 位元的控制／狀態暫存器（MXCSR）。不過只能在 64 位元的模式下才能使用額外 8 個暫存器。

每個暫存器可以容納 4 個 32 位元單精度浮點數，或是 2 個 64 位元雙精度浮點數，或是 4 個 32 位元整數，或是 8 個 16 位元短整數，或是 16 個字元。整數運算能夠使用正負號運算。而整數 SIMD 運算可能仍然要與 8 個 64 位元 MMX 暫存器一起執行。

因為作業系統必須要在程序切換的時候保護這些 128 位元的暫存器狀態，除非作業系統去啟動這些暫存器，否則預設值是不會去啟用的。這表示作業系統必須要知道如何使用 FXSAVE 與 FXRSTOR 指令才能儲存 x87 與 SSE 暫存器的狀態。而在當時 IA-32 的主流作業系統很快的都加入了此功能。

由於 SSE 加入了浮點支援，SSE 就比 MMX 更加常用。而 SSE2 加入了整數運算支援之後讓 SSE 更加的有彈性，當 MMX 變成是多餘的指令集，SSE 指令集甚至可以與 MMX 並行運作，在某些時候可以提供額外的效能增進。

第一個支援 SSE 的 CPU 是 Pentium III，在 FPU 與 SSE 之間共用執行支援。當編譯出來的軟體能夠交叉的同時以 FPU 與 SSE 運作，Pentium III 並無法在同一個週期中同時執行 FPU 與 SSE。這個限制降低了指令管線的有效性，不過 XMM 暫存器能夠讓 SIMD 與純量浮點運算混合執行，而不會因為切換 MMX／浮點模式而產生效能的折損。

SSE 指令表

SSE 提供純量與包裹式（packed）浮點指令。

2.1 浮點指令

記憶體到暫存器／暫存器到記憶體／暫存器之間的資料搬移
純量– MOVSS
包裹式– MOVAPS, MOVUPS, MOVLPS, MOVHPS, MOVLHPS, MOVHLPS
數學運算
純量– ADDSS, SUBSS, MULSS, DIVSS, RCPSS, SQRTSS, MAXSS, MINSS, RSQRTSS
包裹式– ADDPS, SUBPS, MULPS, DIVPS, RCPPS, SQRTPS, MAXPS, MINPS, RSQRTPS
比較
純量– CMPSS, COMISS, UCOMISS
包裹式– CMPPS
資料拆包（unpack）與隨機搬移（shuffle）
包裹式– SHUFPS, UNPCKHPS, UNPCKLPS
資料型態轉換
純量– CVTSI2SS, CVTSS2SI, CVTTSS2SI
包裹式– CVTPI2PS, CVTPS2PI, CVTTPS2PI
逐位邏輯運算
包裹式– ANDPS, ORPS, XORPS, ANDNPS

2.2 整數指令

數學運算
PMULHUW, PSADBW, PAVGB, PAVGW, PMAXUB, PMINUB, PMAXSW, PMINSW
資料搬移
PEXTRW, PINSRW
其他
PMOVMSKB, PSHUFW

2.3 其他指令

MXCSR 管理
LDMXCSR, STMXCSR
快取與記憶體管理
MOVNTQ, MOVNTPS, MASKMOVQ, PREFETCH0, PREFETCH1, PREFETCH2, PREFETCHNTA, SFENCE

例子

下面這個例子演示了使用 SSE 的優點。向量加法在計算機圖形中很常用，如果在 x86 平臺上想將四對單精度浮點數相加，必須使用四對浮點相加指令。

vec_res.x = v1.x + v2.x;

vec_res.y = v1.y + v2.y;

vec_res.z = v1.z + v2.z;

vec_res.w = v1.w + v2.w;

上面這段程式碼會被編譯成 4 條 x86 FADD 指令。下面的虛擬碼展示用 128 位包裹式相加（packed-add）指令替代 4 個純量相加指令。

movaps xmm0, v1 ;xmm0 = v1.w | v1.z | v1.y | v1.x

addps xmm0, v2 ;xmm0 = v1.w+v2.w | v1.z+v2.z | v1.y+v2.y | v1.x+v2.x

movaps vec_res, xmm0

後續版本

4.1 SSE2

SSE2 是 Intel 在 Pentium 4 處理器的最初版本中引入的，但是 AMD 後來在 Opteron 和 Athlon 64 處理器中也加入了 SSE2 的支援。SSE2 指令集添加了對 64 位雙精度浮點數的支援，以及對整型資料的支援，也就是說這個指令集中所有的 MMX 指令都是多餘的了，同時也避免了佔用浮點數暫存器。這個指令集還增加了對 CPU 快取的控制指令。AMD 對它的擴充套件增加了 8 個 XMM 暫存器，但是需要切換到 64 位模式（x86-64/AMD64）才可以使用這些暫存器。Intel 後來在其 Intel 64 架構中也增加了對 x86-64 的支援。

4.2 SSE3

SSE3 是 Intel 在 Pentium 4 處理器的 Prescott 核心中引入的第三代 SIMD 指令集，AMD 在 Athlon 64 的第五個版本，Venice 核心中也加入了 SSE3 的支援。這個指令集擴充套件的指令包含暫存器的區域性位之間的運算，例如高位和低位之間的加減運算；浮點數到整數的轉換，以及對超執行緒技術的支援。

4.3 SSSE3

SSSE3 是 Intel 針對 SSE3 指令集的一次額外擴充，最早內建於 Core 2 Duo 處理器中。

4.4 SSE4

SSE4 是 Intel 在 Penryn 核心的 Core 2 Duo 與 Core 2 Solo 處理器時，新增的 47 條新多媒體指令集，現在 SSE4 版本更新至 SSE4.2。

4.4.1 SSE4a

AMD 也開發了屬於自己的 SSE4a 多媒體指令集，並內建在 Athlon II 與 Opteron 等 K10 架構處理器中，不過 SSE4a 無法與 Intel 的 SSE4 系列指令集相容。目前 AMD 新一代處理器已支援 Intel 的 SSE4.1、SSE4.2 指令集。

4.5 SSE5

SSE5 是 AMD 為了打破 Intel 壟斷在處理器指令集的獨霸地位所提出的，SSE5 初期規劃將加入超過 100 條新指令，其中最引人注目的就是三運算元指令（3-Operand Instructions）及熔合乘法累積（Fused Multiply Accumulate）。其中，三運算元指令讓處理器可將一個數學或邏輯函式庫，套用到運算元或輸入資料。藉由增加運算元的數量，一個 x86 指令能處理二至三筆資料，SSE5 允許將多個簡單指令匯整成一個指令，達到更有效率的指令處理模式。提升為三運算指令的運算能力，是少數 RISC 架構的水準。熔合乘法累積讓允許建立新的指令，有效率地執行各種複雜的運算。熔合乘法累積可結合乘法與加法運算，透過單一指令執行多筆重複計算。透過簡化程式碼，讓系統能迅速執行繪圖著色、快速相片著色、音場音效，以及複雜向量演算等效能密集的應用作業。目前 AMD 已放棄下一代 Bulldozer 核心內建 SSE5 指令集，改內建 Intel 授權 SSE4 系列指令集。

4.6 AVX

AVX（Advanced Vector Extensions）是 Intel 的 SSE 延伸架構，如 IA16 至 IA32 般的把暫存器 XMM 128bit 提升至 YMM 256bit，以增加一倍的運算效率。

4.7 FMA

FMA 是 Intel 的 AVX 擴充指令集，如名稱上熔合乘法累積（Fused Multiply Accumulate）的意思一樣。