タグ:zero-riscy ( 11 ) タグの人気記事

昨日に引き続き、zero-riscy に BNN を高速化する命令を追加します。
Pool 命令は funct3=2 で、rs2 からデータを入れます。
Norm 命令は funct3=3 で、rs1 からアドレスを入れます。
Active 命令は funct3=4 です。結果を rd に戻すのですが、そこら辺の制御が必要。DIV 命令でも参考にするか。

戻すデータとストールは zeroriscy_multdiv_fast.sv の multdiv_result_o と ready_o をたどっていった先にマージします。
他にも zeroriscy_id_stage.sv でマルチサイクル命令のステートマシン変更したり stall 信号を作る必要がありました。
あとは zeroriscy_decoder.sv で regfile_we を上げておくのかな。
とりあえず下の命令が正しい値を表示するので、次回からは推論プログラムを変形していこうと思います。
putx(bnn_activ());
Verilator はちまちま修正するには時間がかかりますねぇ。Model-Sim との効率よい二刀流を考えねば…
ひとまずは zero-riscy のコア だけ登録しました。

[PR]
by tom01h | 2018-01-22 21:38 | PCとか | Trackback | Comments(0)
zero-riscy に BNN を高速化する命令を追加します。
追加する回路は BNN 推論環境 で作った推論アクセラレータ回路そのものです。
まずは Init コマンドと Acc コマンドを命令にします。
とりあえず、Costom0 命令をすべて、BNN アクセラレータ命令に割り当てるくらいのつもりで始めます。
Ini 命令は funct3=0 で、rs2 からデータを入れます。
Acc 命令は funct3=1 で、rs1 からアドレスを、rs2 からデータを入れます。将来的にはアドレスは rs1+imm にしたいと思っていますが…
とりあえずここまで作って、動作確認のために下のようなプログラムを流してみました。
bnn_ini(-288);
bnn_acc(0,0);
bnn_acc(1,0);
bnn_acc(2,0);
bnn_acc(3,0);
bnn_acc(4,0x252de1b0);
bnn_acc(5,0x2d3f61be);
bnn_acc(6,0);
bnn_acc(7,0xb7ade3f3);
bnn_acc(8,0xffbfe3ff);
結果は正しいみたいですがスカスカだ…
f0054075_22282425.png
まあ、最初から分かっていたことではありますけどね。

[PR]
by tom01h | 2018-01-21 23:25 | PCとか | Trackback | Comments(0)
zero-riscy にカスタム命令を追加したいと思います。
まずは試しに ADD 命令を別のコードで実装してみます。
custom0 の命令領域を使う以外は、普通の ADD 命令と全く同じ。
コンパイラサポートはよくわからないので、とりあえずは FPGA マガジンの No18 と同じ方法、.word でアセンブラファイルに直接命令コードを書く、ちょっと格好悪い方法で良いことにしました。
とりあえずやりたいことはできている模様。
明日から BNN アクセラレータ命令追加するぞ!!

[PR]
by tom01h | 2018-01-20 23:37 | PCとか | Trackback | Comments(0)
いよいよ XNOR とビットカウントを使って、最適化最終段階に入ります。
ビットカウントはネットで拾った下の計算。
// C or C++: use uint32_t
i = i - ((i >> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
恐ろしいくらいの最適化ですね。
もちろんこれは、論理演算だろうが掛け算だろうが同じ速度で計算するCPUならではの最適化法です。RTL 設計には当てはまらないのでご注意ください。
話を推論に戻すと、期待以上にだいぶ速くなりました。
置き場所としていまいちかもしれんせんが、Github の zero-riscy のテスト環境 に置いておきました。
f0054075_20205672.png
ちなみに、
オリジナルっていうのは 32bit float だとこのくらいかなって鉛筆なめた数字で、
bin 値のみはパラメータはバイナリ型を int 型に詰め込んでデータサイズを削減しつつ、ワークメモリのほうは整数型を使っているバージョン、
bin 実行順はアクティベーション間の計算順序を幅優先から深さ優先に変更して保存するワークデータ数を削減しつつ、データ型も signed char に変更して使用メモリ量を削減したバージョン、
bin 完成はワークメモリもバイナリ型を int 型に詰め込んで、計算も XNOR + bit カウントに変更したバージョンです

[PR]
by tom01h | 2017-12-22 00:00 | PCとか | Trackback | Comments(0)
推論プログラムで使うワークメモリを減らすために、アクティベーション間の計算順序を幅優先から深さ優先に変更しました。
ついでにアクティベーションデータは±1だけなので、char 型に変更してみたのが運の尽き、大変な目にあいました。
char 型って gcc のバージョンによって、デフォルトが符号付きだったり無しだったりするのでしょうか?
[追記 バージョン依存ではなく、ターゲットアーキテクチャに依存するようです。ご参考まで。]
WSL 上で実行するとちゃんと動くのに、RISC-V 用にコンパイルすると動かない。
逆アセンブルしてみるとなんかおかしい。この解析にとっても時間がかかってしまいました。
そんなわけで、XNOR とビットカウントを使った最適化はまた明日。
f0054075_00101884.png
なんでか知らないけど、実行サイクル数もぐっと減っていますね。

[PR]
by tom01h | 2017-12-21 00:11 | PCとか | Trackback | Comments(0)
Verilator を使って試行中なのですが、割り当てメモリがどんどん増えて、命令32KBとデータ512KBでデバッグしています。
とりあえず1データだけですが、103775576サイクルで完走しました。正しく計算できている模様です。
だいぶ遅いとはいえ、シミュレーションで流して見れるのはやっぱり便利です。Verilator えらい。
いまさらながら、使用メモリ量をざっと見積もってみました。
ここ においてあるソースファイルから、目立つバッファを抜き出しています。
パラメータと計算中のデータを置いておくメモリの合計で約480KBのメモリを使うみたいです。
データメモリを512KBにしたのでぎりぎり間に合っているかな?でもこのままだと、FPGAには乗らなさそうです。
データを置いておくメモリは全く最適化していないし、そもそも32bit整数型の必要もないはずなんですけどね。
f0054075_17490491.png
やっぱりソフトウェアもちゃんと最適化たいと思いますが、まずはデータ削減のために演算順序を変えるところから。
アクティベーションからアクティベーションの間を幅優先から深さ優先に変更します。
これで必要な中間バッファががっつり減ります。
まぁ、本来なら中間バッファの再利用もしたほうが良いのでしょうけどね。
ワークメモリはこれくらいに減る予定です。
f0054075_17474204.png
これなら Arty Z7-20 にも Arty A7-35 にも乗りますかね?
まだ試していませんけど…

[PR]
by tom01h | 2017-12-20 00:00 | PCとか | Trackback | Comments(0)
なかなかうまくいきません。
まずはとにかくメモリを食いすぎる。結局、命令32KBとデータ512KBまで増えちゃいました。まぁ、ソフトの最適化はほとんどしていないのが原因なんですけどね。
でもって、リンカスクリプトの設定ではメモリを増やしたのに、実際のメモリを増やし忘れてさんざんっぱら悩んでました。
そもそもまずは Modelsim で始めたんですが、速度が全然満足できない。Verilator に変えると速くなったんだけど、トレースが出なくなっちゃう。波形をとるのは、さすがに遅くなりそうで試していない。
とにかく即席のトレースをでっちあげて進めていたら、とっても効率が悪かったのです。そしてやっと、入力層の畳み込みのが終わるところまでPCが進みました。計算結果が正しいかの確認はまだですが…
とりあえずこのまま進めるか?トレースを頑張って作るか??
FPGA に持っていくためには、メモリを減らすためのソフト最適化も必要かな。

[PR]
by tom01h | 2017-12-17 23:26 | PCとか | Trackback | Comments(0)

zero-riscy で puts する

zero-riscy の検証環境に、文字列出力機能を追加しました。
そして、C のサンプルプログラムから文字出力を試してみました。
アドレスマップは
0x80000000 ~128KB 命令
0x80100000 ~128KB データ
0x9a100000 ~1B 文字出力用バッファ
0x801ffffc ~1B 終了アドレス

文字出力用バッファに書いた文字が表示されます。
終了アドレスに 1 を書くと PASS します。

[PR]
by tom01h | 2017-12-11 23:49 | Trackback | Comments(0)
なんでか知らないけど C 拡張の tohost レジスタのアドレスがちょっと違ったけど、そこだけ直すと rv32uc-p-rvc もパスしました。
マシンモードのテストに戻ります。
mstatus レジスタの mpp フィールドは、ユーザかマシンに限定するなら1ビットに省略してもよいとあります。
スーパバイザを選べないようにすことで、いろいろなテストを省略して illegal がパスしました。こんなので良いのかどうかは…
さらに変更なくとも scall, shamt がパスしました。
そしてマシン何とかIDレジスタを読み出し0固定で実装すると mcsr がパス。
tselect レジスタを -1 固定読み出しで追加すると breakpoint もパスします。
その際、zero-riscy 固有機能なの?パフォーマンスレジスタがアドレスがかぶっていたので移動しました。
残りのマシンモードテストは sbreak になりました。
ユーザモードの fence.i と合わせて保留かな?
V-scale の時はユーザモードではアクセスできない CSR とか命令とかあったけど、実装しなくてもよいのかな?

[PR]
by tom01h | 2017-11-30 22:02 | Trackback | Comments(0)
チューリッヒ工科大学とボローニャ大学が共同で作っている zero-riscy の調査中です。
rv32ui と rv32um の isa-test を流してみます。
以下の修正をしました。
  • 実装の無い CSRegister へのアクセスは illegal instruction 例外を発生
  • fence/fence.i を NOP 命令として実装
  • mtvec レジスタを書き込み可能にして Direct Mode に対応
  • mstatus レジスタに USER モード追加 ← これ、かなり大規模
  • mcause レジスタに入れる Exception Code の修正 (ecall 時のモード)
この修正で fence.i 以外はパスするようになりました。
fence.i は自己書き換えコードの実行かな?プリフェッチャが付いていて良く分からないので、とりあえず後回しにしたいと思います。
次は rv32mi を試してみたいと思います。
ma_addr と ma_fetch はすぐにパスしました。
次の修正すると csr がパスしました。
  • misa レジスタ追加
  • mscratch レジスタ追加
続く??
そういえば、rv32uc も通るはずなのかな?

[PR]
by tom01h | 2017-11-28 23:17 | Trackback | Comments(0)