FPGA開発日記

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

RISC-Vのベクトル拡張命令の仕様書日本語版を最新仕様v0.8にアップデートした

結構昔にRISC-V Vector Extensionの仕様を日本語化したものを公開していたのだが、公開して移行全くアップデートしていなかったので最新仕様に対応すべく修正を行った。

前回の公開時の記事はこちら。v.0.7.1をベースに執筆している。

msyksphinz.hatenablog.com

今回は最新仕様のv0.8に基づいて修正を行っている。 RISC-V Vector Extensionの仕様書のタグv0.8を参照しながら執筆を行ったので、中途半端な修正ではなくちゃんと正式リリースに対応しているはずだ。

riscv.github.io

そしてこちらが修正を実施した日本語版。

  • RISC-V “V” Extension 日本語版

RISC-V “V” Extension — riscv-v-spec-japanese ドキュメント

あらかじめ断っておきますが、あくまで趣味で翻訳しているものなので間違いや誤訳はかなり含まれていると思います。 これに関してはDog Foodingというか、自分が使うことになったら修正をかけていくと思う。Pull Requestも大歓迎だけれども。

v0.8での変更点

せっかくなので修正点を要約する。v.0.7.1からv0.8において、主に以下の点において修正が加わっている。

  • vlenbレジスタの導入
  • VL以降のベクトル要素についてはゼロ書き込みの仕様であったものが、「値の変更なし」に変えられている。
  • 全体ベクトルレジスタ・ベクトルロードストア命令が新規追加となる。
  • 4倍ビット幅整数乗算加算命令が新規追加となっている。
  • ビット幅拡張飽和付き累積乗算加算命令が全面削除
  • vfredosum命令の導入。

テール要素の扱いについて

特に大きめの修正点としては「VL以降のベクトル要素についてはゼロ書き込みの仕様であったものが、「値の変更なし」に変えられている。」つまりテール要素に対する書き込みのポリシーに変更が加わっている。

これに関してはかなり議論が行われていたようで、以下の示すような議論の履歴を残すメモも公開されていた。

ただし図が全くないので理解が難しいのだが、自分でいろいろ図を書いて調べてみた。主にレジスタリネーミングのポリシをどのように考えるかというところで実装のしやすさが変わる、というところらしい。

  • ベクトルのテール要素(つまり演算対象ではないベクトルの後ろの方)のアップデートを行わない場合(v0.8の仕様)

この場合、まず空間的にベクトルレジスタが配置されている場合(つまりSIMDみたいな感じかしら)、テール要素をどのように扱おうがオーバヘッドは発生しない。同時に演算が実行されるだけである。

f:id:msyksphinz:20200111232523p:plain:w300

ただしこれが時間的なベクトルレジスタ配置(つまり、先頭のベクトルから順番に実行していく場合)の場合、テール要素は無視するだけでなく、リネーム元のレジスタの内容をちゃんとコピーしないと「値の保持」にならない。このためのオーバヘッドが発生する。これがベクトルの長さが大きくなるとバカにできなくなる。

f:id:msyksphinz:20200111232945p:plain:w300

ただしやり方としてはいろいろあって、例えば長いベクトルレジスタをいくつかに分割して細かくリネーミングすることで、例えばテール要素はリネームせずに前のレジスタIDを保持することで「値の保持」が実現できるようになる。ただしこの方式の弱点は、リネームテーブルを余計に消費してしまうことである。

f:id:msyksphinz:20200111233012p:plain
テール要素「値保持」の場合、テール要素のグループのみ「リネームしない」ことによりオーバヘッドを削減する。
  • ベクトルのテール要素(つまり演算対象ではないベクトルの後ろの方)をすべてゼロで埋める場合(v0.7.1の仕様)

ベクトルのテールをすべて0で埋める場合には、「ゼロを書き込む」という操作が必要になり結局オーバヘッドが発生する。

f:id:msyksphinz:20200111233251p:plain:w300
テール要素「ゼロ埋め」の場合、テール要素にゼロを書き込むためのコストが発生する。

ただしこれにも解決方法があって、ある程度のグループで「すべての要素がゼロである(というか、テール要素である)」ビットを付加しておき、そのビットが立っている場合には演算を省略するという方式がある。

f:id:msyksphinz:20200111233446p:plain:w400
ゼロ要素ビットが1になっている場合、そのベクトルレジスタグループは演算を省略する。

さらに、リネームをするタイプの演算であれば、やはりベクトルレジスタグループを細かく分割して、テール要素が含まれているベクトルレジスタグループは常に定数ゼロレジスタにリネームするようにしておけば、コストを省略できる。

f:id:msyksphinz:20200111233628p:plain
ゼロ埋め方式でリネームする場合、テール要素は常にゼロベクトルにリネームすることでコストを削減する。