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

向量暫存器(vector register)

一般暫存器像一個只裝一個數字的信箱。向量暫存器則是一排焊在一起、用一個名字定址的信箱——打開它,你找到的不是一個數字而是一整串,譬如並排坐著的 32 個浮點值。當一條指令指名那個暫存器時,它一次就抓向全部。

在實體上,向量暫存器是一塊寬的儲存體,分成相等的槽位,稱為元素或車道(lane)。一個 512 位元的向量暫存器可裝十六個 32 位元數字,或八個 64 位元數字,或三十二個 16 位元數字——同樣的位元,依指令切成不同的車道寬度。一個向量運算讀兩個這樣的暫存器,把第 0 道配第 0 道、第 1 道配第 1 道,依此類推,在每條車道執行運算,再把結果寫進第三個向量暫存器。各車道彼此獨立,所以同時計算。對記憶體而言,一條向量載入就從一段連續的記憶體把整個暫存器填滿,一條向量儲存則把它全部寫回。

向量暫存器是任何 SIMD 或向量機器看得見的核心——在 x86 是 SSE/AVX 家族的 XMM、YMM、ZMM 暫存器(128、256、512 位元);在 ARM 是 NEON 與 SVE 暫存器。這些暫存器的數量與寬度是指令集架構的一部分,這就是為什麼把它們加寬(SSE 到 AVX 到 AVX-512)會造就一個新的指令集擴展,而舊的二進位檔在重新編譯前無法使用新的寬度。陷阱在於:把一個向量暫存器填滿,只有在你有足夠多相鄰且獨立的資料可填時才划算;半空的向量暫存器會浪費車道。

一個 256 位元的 AVX 暫存器(YMM)裝八個 32 位元浮點數。把陣列的八個元素載入 YMM0、再八個載入 YMM1,發出一條 vaddps,YMM2 現在就裝著那八個逐元素的和——八個加法由一條指令、在一個週期份的車道上完成。

一個具名暫存器,裡頭許多車道;運算同時打中每一條車道。

向量暫存器的寬度是指令集架構的一部分,不是免費的旋鈕。AVX-512 程式無法在只有 256 位元暫存器的晶片上跑;你必須重新編譯,而半滿的向量暫存器會讓車道閒置。

又稱
vector register fileSIMD register向量暫存器組SIMD 暫存器