BNN-PYNQを理解する(3) ハードウェア概要・実装
BNN-PYNQのハードウェアの概要・実装、ソフトウェアのシーケンスなど更新しました。 (追記5/21 上記の更新したつもりができていませんでした。本日更新しました)
https://tkat0.github.io/study-BNN-PYNQ/
論文とアクセラレータ側の実装を読みつつ、概要から順にまとめているところです。
以下、アクセラレータの実装を読んで、C++のテンプレートの使い方が面白いなと感じたので記事にしました。*1
BNN-PYNQのハードウェア実装について
BNN-PYNQのアクセラレータのコアであるMVTU*2の実装を見るとわかりますが、C++のテンプレートで定数を記述してます。
BNN-PYNQ/matrixvector.h at master · Xilinx/BNN-PYNQ · GitHub
最初実装を見たとき、普通の引数で変数を渡せばいいじゃん、と思っていたのですが、これは高位合成したHWの性能を出すために必要なんですね。
高位合成で性能を出すためには、挙動がコンパイル時に静的に決まるような書き方をすることがポイント
C++のテンプレートを使えば、関数呼び出し毎に定数を変えられる(定数の異なる関数を生成できる)
C++のテンプレートを上手く使うと、ハードウェア化したときに性能がでるC++コードを簡単に記述できて便利だと思いました。
高位合成の実装をするときは、こんな感じで使い分ければよいかな?
- コンパイル時に決定できる定数(ノード数など)
- 関数呼び出し毎に変えたいパラメータ
- →テンプレート定数
- 関数呼び出し毎に同じパラメータ
- →定数(const)
- 関数呼び出し毎に変えたいパラメータ
- コンパイル時に決定できない変数(バッチサイズなど)
- →引数で変数を渡す
ただし、Vivado 2017.1では可変長のループでも最適化されるようになったとの噂。 もしかして、今後は上記のような実装を意識しなくても効率的な実装ができるのかな?