FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

RISC-VのGPGPU実装であるVortexのビルドメモ

以下のリポジトリでVortexのソースコードをCloneできる。

github.com

  • Specifications
    • Support RISC-V RV32IMF ISA
    • Scalability: 1 to 32 cores with optional L2 and L3 caches
    • Software: OpenCL 1.2 Support
    • Supported FPGAs:

とりあえずREADMEを読みながらビルドしてみた。

git clone --recursive https://github.com/vortexgpgpu/vortex.git
cd vortex
make
      |          ^
%Warning-EOFNEWLINE: ../dpi/util_dpi.vh:10:7: Missing newline at end of file (POSIX 3.206).                                            : ... Suggest add newline.
   10 | `endif
      |       ^
%Warning-EOFNEWLINE: ../rtl/libs/VX_index_buffer.v:90:10: Missing newline at end of file (POSIX 3.206).                                                        : ... Suggest add newline.
   90 | endmodule
      |          ^
%Warning-EOFNEWLINE: ../rtl//VX_csr_data.v:217:10: Missing newline at end of file (POSIX 3.206).                                                 : ... Suggest add newline.
  217 | endmodule
      |          ^
%Warning-EOFNEWLINE: ../rtl/fp_cores/VX_fpu_fpnew.v:209:12: Missing newline at end of file (POSIX 3.206).                                                          : ... Suggest add newline.
  209 | `TRACING_ON
      |            ^
%Warning-EOFNEWLINE: ../rtl/libs/VX_serial_div.v:100:10: Missing newline at end of file (POSIX 3.206).                                                       : ... Suggest add newline.
  100 | endmodule
      |          ^
%Warning-UNUSED: ../rtl//VX_lsu_unit.v:26:16: Parameter is not used: 'REQ_ADDRW'
                                            : ... In instance Vortex.genblk2[0].cluster.genblk2[0].core.pipeline.execute.lsu_unit
   26 |     localparam REQ_ADDRW  = 32 - REQ_ASHIFT;
      |                ^~~~~~~~~
                 ../rtl//VX_execute.v:65:1: ... note: In file included from VX_execute.v
                 ../rtl//VX_pipeline.v:194:1: ... note: In file included from VX_pipeline.v
                 ../rtl//VX_core.v:86:1: ... note: In file included from VX_core.v
                 ../rtl//VX_cluster.v:55:1: ... note: In file included from VX_cluster.v
                 ../rtl//Vortex.v:53:1: ... note: In file included from Vortex.v
%Warning-UNUSED: ../rtl/libs/VX_stream_arbiter.v:23:16: Parameter is not used: 'LOG_NUM_REQS'
                                                      : ... In instance Vortex.genblk2[0].cluster.genblk2[0].core.pipeline.commit.writeback.rsp_arb
   23 |     localparam LOG_NUM_REQS = $clog2(NUM_REQS);
      |                ^~~~~~~~~~~~
                 ../rtl/cache/VX_cache.v:537:1: ... note: In file included from VX_cache.v
                 ../rtl//Vortex.v:102:1: ... note: In file included from Vortex.v
%Error: Exiting due to 87 warning(s)

うーん、大量にエラーが出てきてしまった。Verilatorのバージョンがあっていないのか?

マイクロアーキテクチャについて

以下のドキュメントを読んでみる。

github.com

Vortexマイクロアーキテクチャ

Vortex GPU実行モデル

VortexはSIMT (Single Instruction, Multiple Threads) の実行モデルを使用しており、単一のWarpがサイクル毎に発行される。

  • スレッド
    • 計算の最小単位
    • 各スレッドレジスタファイルを持っている(32個の整数、32個のFPレジスタ)
    • スレッドは並列に実行される
  • Wrap
    • スレッドの論理的なクラスタ
    • Warp内の各スレッドhh同じ命令を実行する
      • PCは共有され、ライトバックのためにスレッドのマスクが管理されている
    • Warpは長いステップで時分割されて実行される
      • 例: Warp0はサイクル0で実行され、Warp1はサイクル1で実行される

Vortex RISC-V命令拡張

  • スレッドマスク制御
    • 実行中にアクティブなWarpの数を制御する
    • TMC count: count数のスレッド数をアクティベートする
  • Warpスケジューリング
    • 実行中に起動するWarpの数を制御する
    • WSPAWN count, addr: count分だけWarpを起動し、addrの位置にジャンプする。
  • コントロールフローの分岐
    • 分岐したときに起動するスレッドを制御
    • SPLIT predicate: 'taken' 述語のスレッドマスクを適用し、 'not-taken' を IPDOM スタックに保存する。
    • JOIN: 'not-taken' スレッドマスクの復元
  • ワープの同期
    • BAR ID, count: バリアIDに入るワープをカウント数に達するまでストールする

Vortexパイプライン/データパス

f:id:msyksphinz:20210914000008p:plain
  • フェッチ
    • Warpスケジューラ
      • ストールしたWarpとアクティブなWarpの追跡、分岐とバリアの解決、分割/結合IPDOMスタックの維持
    • 命令キャッシュ
      • キャッシュからの命令の取得、I-cacheリクエスト/レスポンスの発行
  • デコード
    • フェッチされた命令をデコードし、以下の命令がデコードされたらWarpスケジューラに通知する
      • 分岐、tmc、split/join、wspawn
    • used_regs mask の事前計算 (Issueステージに必要)
  • 発行
    • スケジューリング
      • インオーダ発行(オペランド/実行ユニットの準備)、アウトオブオーダコミット
    • IBuffer
      • フェッチされた命令を格納し、Warpごとにキューを分け、ラウンドロビン・スケジューリングによって次のWarpを選択する
    • スコアボード
    • GPR(General-Purpose Registers)ステージ
  • 実行ユニット
    • ALUユニット
      • シングルサイクル演算(+,-,>>,<<,&,|,^)、分岐命令(ALUリソースの共有
    • MULDIVユニット
      • 乗算器 - 2サイクルで実行
      • 除算器 - 除算と余剰、32サイクルで実行
    • FPUユニット
      • マルチサイクル演算、ASICではFPnewライブラリを使用、FPGAではハードDSPを使用
    • CSRユニット
      • バイス・キャップ、FPUステータス・フラグ、パフォーマンス・カウンタなどの恒常的なステータス・レジスタの格納
      • 外部からのCSRリクエスト(ホストCPUからのリクエスト)に対応
    • LSUユニット
      • ロード/ストア操作の処理、D-キャッシュ要求の発行、D-キャッシュ応答の処理
      • ロードレスポンスのコミット - ストレージの保存、スコアボードによる完了の追跡
    • GPGPUユニット
      • GPGPU命令の処理
        • tmc、wspawn、split、bar
      • JOINはWarp Schedulerが処理します(SPLIT応答時)。
  • コミット
    • コミット
      • CSRフラグの更新、パフォーマンスカウンタの更新
    • ライトバック
      • 結果のGPRへの書き戻し、スコアボードへの通知(使用中レジスタの解放)、候補命令の選択(ALUユニットが最優先
  • クラスタリング
    • 複数のコアをクラスタにまとめる(L2キャッシュを共有することも可能)
    • 複数のクラスタをグループ化(L3キャッシュの共有も可能)
    • ビルド時に設定可能
    • デフォルトの設定。
  • FPGA AFUインターフェース
    • CPU-GPU間通信の管理
      • バイスキャップの照会、カーネル命令とリソースバッファの読み込み、カーネル実行の開始、デスティネーションバッファの読み込み
    • ローカルメモリ - GPUによるローカルDRAMへのアクセス
    • 予約済みI/Oアドレス - ホストCPUへのリダイレクト、コンソール出力