資料層級平行:SIMD、向量與 GPU

單指令多資料(SIMD)

/ sim-dee /

想像一個印章,它的章面不是一塊橡膠而是八塊並排、沾的是同一種墨。按一下就在一個動作裡蓋了八個信封。一條 SIMD 指令就是那個印章。SIMD 是單指令多資料(single instruction, multiple data)的縮寫:一條指令,只提取與解碼一次,就對好幾個資料元素同時做相同的運算,每個元素各佔一條寬暫存器裡的車道(lane)。

具體說,一條 SIMD 加法不是拿兩個 32 位元數字算出一個和。它拿兩個 256 位元暫存器,把每個當作八個並排的 32 位元數字,一次算出八個和——第 0 道加第 0 道、第 1 道加第 1 道,依此類推,全在同一個硬體週期裡完成。處理器只提取與解碼了一條指令,所以提取、解碼與迴圈計數這些每元素的額外開銷被攤分到所有車道上。速度就來自這裡:不是每個元素的算術更快,而是每個元素的雜務少得多。

SIMD 是 Flynn 分類四格之一,與 SISD(樸素純量 CPU:一指令一資料)、MIMD(許多核心,各有自己的指令與資料——那是多核心),以及罕用的 MISD 並列。SIMD 是向量處理器構想的引擎、烤進一般 CPU 的 SSE/AVX/NEON 擴展,以及(以一種放鬆、帶執行緒味、稱為 SIMT 的形式)GPU 背後的動力。它的硬限制在於誠實面對自己的形狀:每條車道在同一步都必須做相同的運算。若第 3 道需要不同的運算,或想往不同方向分支,SIMD 沒有乾淨的答案,而你會為此付出代價。

x86 的 addps:一條指令把兩個 128 位元暫存器當成四對 32 位元浮點數相加,一次產生四個和。純量版需要四條獨立的加法指令,外加四次載入與四次儲存;SIMD 版用一條指令、配合寬載入,完成那四個加法。

一條指令、數條車道、每條車道做相同運算——這就是 SIMD 的精髓。

SIMD 不是多核心。多核心(MIMD)讓每個核心有自己獨立的指令流;SIMD 是讓一條指令流帶許多資料車道。它們解決不同問題,好的系統兩者都用。

又称
single instruction multiple data單指令多資料