FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages

RISC-V Workshop Zurichで発表されたRISC-V Vector Extension 0.7.1

RISC-V Workshop Zurichで発表されたRISC-V Vector Extension 0.7.1の資料がアップロードされたので、さっそく概要を把握してみる。

ちなみに、詳細な資料はこちらを参照した方がよい。

github.com


ベクトル命令のアップデート

RISC-Vの"V"拡張について。Ver 0.7が公開されている。詳細は https://github.com/riscv/riscv-v-spec を参照のこと。

RISC-VのVector拡張についての概要。32本のベクトルレジスタが定義される。各レジスタの要素はVLMAXで定義される要素までを最大で格納することができる。このVLMAXRISC-Vコアの実装に依存する。

  • 命令
    • ロードストア・スキャッタ・ギャザー
    • 整数・固定小数点・浮動小数点命令を備える。
    • ベクトル・ベクトル演算、ベクトル・スカラ演算、ベクトル・即値命令を備える
    • 複数精度のサポートおよび命令バンド幅を削減するために、複数のベクトルレジスタを合わせてより長いベクトルレジスタを定義可能。
    • カスタムデータ型およびカスタムデータ幅をサポートするための拡張領域が存在する。
  • 主要なCSR

    • vtypeレジスタ : 各ベクトルレジスタでどの型のデータ(16ビット整数、32ビット整数、など)を格納することができるのかを格納するためのCSRを備える。
      • データの型情報を命令側ではなくレジスタ側に持たせる。これにより命令フィールドのサイズを32ビットでキープする。
      • vsew フィールド : standard element width (SEW = 8, 16, 32, ... , 1024)
      • vlmul フィールド : vector length multiplier (LMUL = 1, 2, 4, 8)
      • vediv フィールド : vector element divider (EDIV = 1, 2, 4, 8)
    • vlレジスタ : 各ベクトル演算命令において、有効な要素が格納されている要素の長さを示す。したがってvl < VLMAXである必要がある。
    • vstart
    • fcsr (vxrm / vxsat) : 固定小数点の丸めモードおよびFP CSRのSaturationフラグを格納している。
  • ベクトル命令のパラメータ

    • ELEN : ビット内の最大要素
    • VLEN : ベクトルレジスタ内のビット数。VLEN >= ELEN
    • SLEN : ビット内のストリップ距離 VLEN >= SLEN >= ELEN
  • VLMAXVLEN(ベクトルレジスタビット長) / 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

混合精度をサポートするために

  1. 例えば32-bitのデータと16-bitのデータに対して演算を行うために必要なのは、VLMAXの値を保持するためにより多くのベクトルレジスタが必要となる。
  2. データパスを増大させないために、レジスタ内のデータを綺麗に並べておく必要がある。

これをサポートするために、vtypeレジスタ内のvlmulフィールドにより、ベクトルレジスタをグループ化することができる。LMUL=1,2,4,8VLMUX = 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

ソフトウェアサポート