SSE (英特爾)

**SSE**（**Streaming SIMD Extensions**）係英特爾喺AMD嘅3DNow!發佈咗一年之後，喺佢嘅電腦芯片奔騰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係奔騰III，喺FPU同SSE之間共用執行支援。當編譯出嚟嘅軟件可以交叉同時以FPU同埋SSE運作，但係奔騰III並冇得喺同一個周期中同時執行FPU同SSE。呢個限制降低咗指令管線嘅有效性，不過XMM暫存器可以俾SIMD同純量浮點運算混合執行，而唔會因為切換MMX／浮點模式而產生性能嘅折損。

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

### 浮點指令
* 記憶體到暫存器／暫存器到記憶體／暫存器之間嘅資料搬移
** 純量– 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

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

### 其他指令
* MXCSR管理
** LDMXCSR, STMXCSR
* 快取同記憶體管理
** MOVNTQ, MOVNTPS, MASKMOVQ, PREFETCH0, PREFETCH1, PREFETCH2, PREFETCHNTA, SFENCE
## 例子
下面呢個例子演示咗用SSE嘅優點。向量加法喺電腦圖形入面好常用，如果喺x86平台上想將4對單精度浮點數相加，一定要使用4對浮點相加指令。

 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個純量相加指令。

```asm
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
```

## 後續版本
### SSE2
SSE2係英特爾喺奔騰4處理器嘅最初版本中引入嘅，但係AMD之後喺Opteron同Athlon 64處理器中加入咗SSE2嘅支持。SSE2指令集添加咗對64位雙精度浮點數嘅支持，同埋對整型數據嘅支持，亦即係話呢個指令集中所有嘅MMX指令都係多餘㗎啦，同時都避免咗佔用浮點數寄存器。呢個指令集仲增加咗對CPU快取嘅控制指令。AMD對佢嘅擴展增加咗8個XMM寄存器，但係要喺64位模式（x86-64/AMD64）先可以用呢啲寄存器。英特爾之後喺X86-64架構中都增加咗對X86-64嘅支持。
### SSE3
SSE3係英特爾喺奔騰4處理器嘅Prescott核心入面引入嘅第三代SIMD指令集，AMD喺Athlon 64嘅第5個版本，Venice核心入面都加入咗SSE3嘅支持。呢個指令集擴展嘅指令包含寄存器嘅局部位之間嘅運算，例如高位同低位之間嘅的加減運算；浮點數到整數嘅轉換，同埋對超綫程技術嘅支持。

### SSSE3
SSSE3係英特爾針對SSE3指令集嘅一次額外擴充，最早內建喺Core 2 Duo處理器中。

### SSE4
SSE4係英特爾喺Penryn核心嘅Core 2 Duo同Core 2 Solo處理器嘅時候推出，新增咗47條新多媒體指令集，依家SSE4版本更新到SSE4.2。
#### SSE4a
AMD都開發咗屬於自己嘅SSE4a多媒體指令集，內建喺Phenom同Opteron等K10架構重有AMD FX處理器入面，不過冇得同英特爾嘅SSE4系列指令集相容。依家AMD新一代處理器已經取消支援SSE4a，改為支援英特爾嘅SSE4.1指令集（含以上）。

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

### AVX
AVX（Advanced Vector Extensions）係英特爾嘅SSE延伸架構，好似IA16至IA32咁將暫存器XMM 128位元提升到YMM256位元，以增加一倍嘅運算效率。

### FMA
FMA指令集係英特爾嘅AVX擴充指令集，個名同熔合乘法累積（Fused Multiply Accumulate）嘅意思一樣。