人気ブログランキング | 話題のタグを見る

雑多な趣味の記録帳

tom01h.exblog.jp

Verilator を OpenMP で高速化

Varilator はせっかく高速なシミュレータなのに、シングルスレッドでしか動作しない。どうせテストベンチはC++なのだから、今どきの並列化手法が使えるのじゃないか?ちょっと調べてみると、MPIのほうが高速になるらしいけど、OpenMPのほうが簡単(変更量が少ない)そうなので、こっちを使うことにした。期待はずれかもしれませんが、回路の分割じゃなくて、テストベクタの分割ですよ。それならタスクで分割すればいいじゃんて言われたらごもっとも。
まずは適当にググって最外ループを並列化してみた。軒並みフェイルしますよ。どうやら、並列化するループ内の変数を、private宣言しなくてはならないらしい。Verilatorで言うと、並列化する分だけ対象回路をインスタンスするって事か?まぁ、当然のような気もするが、なんかもったいないよね。なので、最外ループを分割してみました。
やりかたを大雑把に。元のテストベンチがこんな感じなら
Vhoge* verilator_top = new Vhoge;
for(i=0; i<100; i++){
verilator_top->in=i;
verilator_top->eva l();
if(verilator_top->out != hoge){
printf("NG\n");
}
}
delete verilator_top;
こんな風にします
Vhoge* verilator_top;
#ifdef _OPENMP
#pragma omp parallel for private(i,verilator_top)
#endif
for(t=0; t<10; t++){
verilator_top = new Vhoge;
for(i=t*10; i<(t+1)*10; i++){
verilator_top->in=i;
verilator_top->eva l();
if(verilator_top->out != hoge){
printf("NG\n");
}
}
delete verilator_top;
}

Verilator のオプションに以下を追加します。
--CFLAGS -fopenmp
--LDFLAGS -fopenmp
さらにループがネストしたりしていたら、例えばjもprivate宣言に追加します。
これでとりあえずパスはするようになったし、高速化もできました。もともと4コア8スレッドで17-8%のCPU使用率が100%になって、4-5倍ほど高速化してます。単純な回路の網羅的検証には有効なようです。ただし、ちゃんと検証できているかの確認は簡単にしかしていません。

by tom01h | 2017-05-23 20:45