在進程切換時，作業系統必須管理 SSE 暫存器的狀態以確保不同進程之間的穩定與安全。由於 SSE 使用的是 128 位元的暫存器，在進程切換時，作業系統需要使用 `FXSAVE` 和 `FXRSTOR` 指令來儲存和恢復這些暫存器的狀態。這表示，作業系統必須明確知道如何處理這些暫存器，並在進程切換時進行必要的上下文切換。

這樣的管理對程式的運行效率有幾個方面的影響：

1. **上下文切換的開銷**：在進程切換過程中，保存和恢復 SSE 暫存器的狀態會增加額外的計算開銷。這可能會導致進程間的切換延遲，降低整體系統效能。

2. **記憶體訪問**：因為需要讀取和寫入暫存器的狀態，這也會增加記憶體訪問次數，進而影響存取速度和效能。

3. **多執行緒與 SIMD 效率**：如果程式設計中大量依賴 SSE 指令集進行並行運算，那麼在多執行緒環境中進程切換的效能損失可能更為明顯，因為每次切換都需要保存和恢復執行狀態。

總結來說，進程切換時對 SSE 暫存器的管理確實會影響程式的運行效率，特別是在高頻繁切換的情況下，這樣的開銷會對整體性能造成顯著影響。為了優化效能，作業系統和應用程式設計者需考量這些影響並進行適當的優化。
在進程切換時，如何影響作業系統對 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）浮點指令。

### 浮點指令

* 記憶體到暫存器／暫存器到記憶體／暫存器之間的資料搬移
  * 純量– 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 平台上想將四對單精度浮點數相加，必須使用四對浮點相加指令。

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

## 後續版本

### 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 的支援。

### SSE3

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

### SSSE3

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

### SSE4

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

#### SSE4a

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

### SSE5

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

### AVX

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

### FMA

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

## 參見

* AltiVec
* 組合語言
* MMX
* 3DNow!
* Pentium III
## 問題定義

計算機的 CPU 往往用暫存器來保存指令的操作數與結果。x86 指令集體系結構有 8 個整數暫存器，x86-64 指令級體系結構有 16 個整數暫存器，許多 RISC 體系結構有 32 個整數暫存器，IA-64 有 128 個整數暫存器。在小型處理器，這些指令集體系結構暫存器直接對應於暫存器堆中的物理暫存器。

不同的指令可以有不同的執行時間，特別是 CISC 指令集體系結構上更為明顯。例如，一條讀內存的指令的執行時間，足夠執行幾百條其它指令。因此，在允許多條指令並行執行的情況下，那些指令地址順序靠後的指令，比讀取內存指令更早完成，這就形成了指令執行順序不同於其在程序中的順序。這種亂序執行是高性能 CPU 提高運算速度的關鍵辦法之一。

考慮下述代碼片段在亂序執行 CPU 上的運行：

第 4、第 5、第 6 條指令在功能上是不依賴於第 1、第 2、第 3 條指令的。但是處理器卻不能在第 3 條指令完成前去完成第 4 條指令（在指令流水線上，不能在第 3 條指令完成前，就提交第 4 條指令的結果），因為這可能會導致第 3 條指令把錯誤的數據寫入內存。

通過改變一些暫存器的名字，可以使上例中指令並行執行所受的限制：

現在，4、5、6 號指令可以與 1、2、3 號指令並行執行，二者沒有依賴問題。這使得程序可以用更短時間完成。 ## 新指令所帶來的改變

SSE3 最值得一提的新功效特點，是水平式的暫存器整數運算，而在此之前的 SSE、SSE2 則僅能垂直運算。更進一步的特點是，指令執行時對多筆數值的同時加法運算、減法運算等，之後將結果進行儲存等，都可以在單一個暫存器完成，因此 SSE3 可以用更簡單的方式來實現同時間的多筆、大量 DSP、3D 性質的運算。

此外，有個新指令可將浮點數數值轉換成整數數值，且進行此種轉換不需要將運算切換到 rounding 模式，過去此類轉換必須先切換至 rounding 模式，完成轉換後再登出 rounding 模式，此新指令可省去此模式切換程式，使整體運算更為加速，也因此可避免鄰近執行管線（Instruction pipeline）因此而停緩、等待（模式切換會使後續執行暫停，進而減損運算效能）。

另外，新增設的 LDDQU 指令能夠在交替載入長度不一的整數向量值時獲得更佳的效能，此指令可以讓 Intel NetBurst 架構的執行核心跨越快取線的界線而進行數值載入。 ## 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**（英語：Streaming SIMD Extensions）是英特爾在 AMD 的 3D Now! 發布一年之後，在其電腦晶片 Pentium III 中引入的指令集，是繼 MMX 的擴充指令集。SSE 指令集提供了 70 條新指令。AMD 後來在 Athlon XP 中加入了對這個新指令集的支援。