RISC-V Workshop Zurichで発表されたRISC-V Vector Extension 0.7.1の資料がアップロードされたので、さっそく概要を把握してみる。
ちなみに、詳細な資料はこちらを参照した方がよい。
ベクトル命令のアップデート
RISC-Vの"V"拡張について。Ver 0.7が公開されている。詳細は https://github.com/riscv/riscv-v-spec を参照のこと。
RISC-VのVector拡張についての概要。32本のベクトルレジスタが定義される。各レジスタの要素はVLMAX
で定義される要素までを最大で格納することができる。このVLMAX
はRISC-Vコアの実装に依存する。
- 命令
主要なCSR
ベクトル命令のパラメータ
ELEN
: ビット内の最大要素VLEN
: ベクトルレジスタ内のビット数。VLEN >= ELEN
SLEN
: ビット内のストリップ距離VLEN >= SLEN >= ELEN
VLMAX
はVLEN
(ベクトルレジスタビット長) /SEW
(ベクトルレジスタの要素のビット幅)で算出される。- 現在の有効なベクトル長は
vl
レジスタによって取得できる。これは0 <= vl <= VLMAX
である必要がある。
ベクトル制御命令
vlsetvli rd, rs1, imm
:rs1
にアプリケーションベクトル長(Application Vector Length : AVL)を指定する。immにvtype
のエンコーディング<vsew, vlmul, vediv>
を指定する。rd
には算出されるvl
が返されるmin(AVL, VLMAX)
例 :
memcpy
# void*memcpy(void*dest,constvoid*src, size_tn) # a0=dest, a1=src, a2=n memcpy: mv a3, a0 # Copy destination loop: vsetvli t0, a2, e8 # ベクトルの要素を8-bitに設定 <11101000> vlb.v v0, (a1) # ベクトルレジスタv0にデータをロード add a1, a1, t0 # ポインタを進める。 sub a2, a2, t0 # カウンタをデクリメントする。 vsb.v v0, (a3) # ベクトルレジスタの値をメモリにストアする。 add a3, a3, t0 # ポインタを進める。 bnez a2, loop # まだ要素が残っているか? ret # Return
混合精度をサポートするために
- 例えば32-bitのデータと16-bitのデータに対して演算を行うために必要なのは、
VLMAX
の値を保持するためにより多くのベクトルレジスタが必要となる。 - データパスを増大させないために、レジスタ内のデータを綺麗に並べておく必要がある。
これをサポートするために、vtype
レジスタ内のvlmul
フィールドにより、ベクトルレジスタをグループ化することができる。LMUL=1,2,4,8
。VLMUX = LMUL * VLEN / SEW
となる。
ベクトル命令は、グループ化されたレジスタすべてに適用される。
セグメントロードストア
vlseg3b.v v4, (x10)
という命令をサポートする。
RGBなどの3つの並んだデータ(Array of Struct)を、ベクトル要素毎に並べ替えて格納する(Struct of Array)。※あれ、この命令どこかで見たような...
例外のサポート
ベクトル要素のロード中に例外が発生した場合、vstart
システムレジスタが、どの要素まで処理を行っていたを記録しており、次のベクトル命令でその位置から操作を再開する。vstart
システムレジスタは、ベクトル命令が新たに実行される度に0に初期化されるので、ユーザプログラム自身はvstart
を意識する必要はない。
Divide Elements
より小さなデータをサポートするためにSEWのデータをさらに分割することができる。EDIV=1, 2, 4, 8
。