RISC-V Vector Extension(RVV)是一套為高效資料平行處理而設計的指令集,與傳統 SIMD 架構相比,RVV 提供了更具彈性與可擴展性的解法。本章整理我在學習 Vector Extension 的第一階段心得,從為什麼需要 Vector 開始,到與其他架構的比較,再到幾個基本術語的釐清。
為什麼需要 Vector Extension?
當今處理器的主要瓶頸早已不在時脈或單一指令延遲,而是「資料處理量」。無論是圖像處理、機器學習、科學模擬,這些應用都有一個共通特性:大量且結構規律的資料處理需求。
這正是 Vector Extension 的用武之地——讓硬體在一條指令下就能處理多筆資料(data-level parallelism),大幅提升效能。
傳統 SIMD vs. Vector ISA 的差異
傳統 SIMD(如 x86 SSE/AVX 或 ARM NEON)多屬於「固定寬度」架構。也就是說,128-bit 或 256-bit 是寫死的,一旦程式針對這個寬度最佳化,在不同硬體上就失去移植性。
RISC-V Vector ISA 則屬於「可變長度向量(VLA, Vector-Length Agnostic)」設計,它的特色在於:
- 指令不綁定具體的向量長度
- 實際能處理多少元素由 vsetvl 設定,硬體動態給出 VL
- 程式碼可隨硬體向上相容
簡單說,傳統 SIMD 是「寫死寬度,靠人配硬體」,而 RVV 是「抽象寬度,讓程式跑在哪都能 scale」。
RVV 相較於 AVX、NEON 的優勢
| 特性 | AVX (x86) | NEON (ARM) | RVV (RISC-V Vector) |
|---|---|---|---|
| 向量長度 | 固定(如 256b) | 固定(128b) | 可變,動態決定(VLEN) |
| 擴展性 | 寬度變更需重編 | 固定硬體綁死 | 編碼與寬度無關,自動調整 |
| 指令語法 | 寫死寬度 | 寫死寬度 | 語法與寬度解耦 |
| Tail/Mask 支援 | 限制較多 | 較不彈性 | 原生支援 tail/mask 操作 |
| Compiler 支援 | 成熟 | 成熟 | 正快速成長中 |
Vector 寬度與 VLEN(Vector Register Length)
在 RVV 中,實體向量暫存器的寬度由 VLEN(以 bit 為單位)定義,例如 128b、256b、512b,甚至 1024b,取決於實作。
注意幾個重點:
- VLEN 是硬體定義的固定值(例如 VLEN = 256)
- VLEN 對軟體是不可見的,但會影響最大可設定的 VL
- 軟體只能透過 vsetvl 詢問目前有效的 VL 值(實際可處理幾筆資料)
這種「抽象硬體寬度」的設計讓 RVV 在設計 library 或 runtime 時更具彈性,也更容易 scale 到未來的更寬硬體。
註冊檔長度與可變寬度的彈性
RVV 中的 vector register 整體架構如下:
- 共 32 組向量暫存器:v0 ~ v31
- 每組大小為 VLEN bits
- 支援「register grouping」:透過 lmul 設定使用多個暫存器組成一組大的暫存器(如 v0 + v1 合併為一組)
範例如下:
- LMUL=1: 正常一組 v register
- LMUL=2: 使用兩個 register(如 v0+v1),可處理更大元素數或更寬的資料型別
- LMUL=1/2: 一個 register 可切分處理多個小向量(用於小資料型別節省空間)
基本術語解釋
| 術語 | 說明 |
|---|---|
| vtype | 控制向量型別的暫存設定:資料型別(SEW)、LMUL、mask enable 等 |
| vl | 實際這次指令要處理幾個 element,由 vsetvl 產生 |
| vlenb | VLEN 對應的 byte 單位大小,例如 VLEN=256 ⇒ vlenb=32 |
| lmul | Length Multiplier,設定向量暫存器的組合倍數(可為 1/8 ~ 8) |
| sew | Selected Element Width,向量元素的資料寬度(如 8/16/32/64 bits) |
| vmask | 向量遮罩,用來選擇是否啟用該 element,常與 mask 指令搭配 |
結語
RVV 的設計跳脫傳統 SIMD 的限制,從 ISA 層面就支援可變長度、彈性運算、tail/mask 等關鍵功能。本章以概念性理解為主,下一章我會實際走進幾條指令(例如 vadd.vv, vmul.vx)與它們的語意分析與 RTL 行為拆解,讓整體學習從「抽象」過渡到「具體」。

發表留言