CF

ああCPU実験

理情といえばCPU実験、CPU実験といえば理情です。多分そうです。

書くことが思いつかないのでこれから理情に来る方、もしくはCPU実験が何をやっているのかを知りたいという方向けにCPU実験は大体どんなものであるかということを紹介しようと思います。

概観

そもそも何をするのでしょうか?CPUを作るのでしょうか。誤解を恐れずに言えば、そうです。CPUを作ります。 min-camlという言語で記述されたレイトレーシングプログラムが与えられ、それをFPGAの上で実行するというのが目標です。 即ち、よっぽど変なことをしない限りにおいては、そのmin-camlのコンパイラを作成し、できたアセンブリアセンブルし、そしてそれを解釈するFPGAを作成するというのがCPU実験の全容です。もちろんアセンブリの仕様、ないし機械語の仕様は自由で、既存のRISCVなどを用いてもよいですし、自分で設計しても構いません。 また、外部から入力が与えられないのでは置物ですから、引数などはPCからUARTを用いて与えられます。 それらすべてを一人で行うのは厳しいですから、4人、ないし3人の班でこれを分担します。主にコンパイラを作成するコンパイラ係、FPGAを設計するコア係、FPGAの動くべき動作をソフトウェア的に再現するシミュレータ係、および浮動小数点演算の回路を担当するFPU係に分かれることになります。 この中にはアセンブリを作る係がいませんが、凡そコンパイラ係かシミュレータ係が担当するようです。

お仕事

コア係の仕事

CPUを実装すると言いましたが、FPGAを用いる関係上、はんだごてなどを使う機会はありません。Verilogなどを用いて記述します。自分はあまりこの手の言語に詳しくないのでよくわかりませんが、シミュレーション用の言語であって、一部分がたまたまハードウェアの設計?記述?に使えるらしいという話らしいです。なので時たまかなりプログラミング言語とは思えないほど空気を読む必要が生じるらしいですが、それはきっとコア係になればわかると思います。 何はともあれ、メモリブロックやらを配置し、ALUを作り、デコードして計算してメモリアクセスしてレジスタ書き戻して……な感じのステートマシンを書くみたいです。ハードウェア実験でステートマシン自体は作るしマルチサイクルっぽいこともするので、そこら辺を参考にできそうですね。

コンパイラ係の仕事

コンパイラ係はmin-camlというOCamlのサブセットのような言語のコンパイラを作ります。とはいえ、x86SPARC向けのコンパイラは既に存在しているので、それを改造する形で作成することもできます。もちろんフルスクラッチで作っても構いません。 コンパイラ係は最適化なども含めるとかなりやることが多岐にわたります。そのためか、コンパイラ実験という名前で講義も行われています(コンパイラ係用の課題もありますが全員受けます)。

シミュレータ係の仕事

シミュレータ係は、FPGAがどのように動作すべきかをソフトウェア的に再現します。シミュレータ係の作成したシミュレータと実機の出力が一致することが単位取得の条件とのことなので、「コア係が一発で動かせばシミュレータいらなくね?」は理論的には真ですが単位的には偽です。実用的にも多分偽です。 使用言語は任意です。

FPU係の仕事

FPU係はVerilogなどを用いて浮動小数点演算を実装します。コア係の職掌では?と思う方もいるかもしれません。実際Verilogという意味ではそうなのですが、浮動小数点数計算というのは例えば加算一つ取るだけでも工夫し所があり、予想する以上に深い世界が待っています。夏学期のハードウェア実験のオプション課題の中にFloatの加算を実装するものがありますが、それをやってみれば高速化のための奥深さ、或いはめんどくささが分かると思います。

シミュレータ係の今までしたこと

自分はシミュレータ係なので、全体・シミュレータ係で今やっていること、今までやってきたことを振り返っておきます。

命令アーキテクチャ決め

シミュレータを作るにはまず命令をデコードしなければなりませんから、その規約が必要です。一先ずはRISC-Vに則ることにしました。他の班ではMIPS,自作アーキテクチャなどありました。成果を比較できるのはまだ先になりそうです。

アセンブラを作る

アセンブラはそこまで難しくありません。パースして疑似命令を解してラベルを解消して出力するだけです。しかしその割にバグを生みがちなので、バグを生まないようにアセンブラを自動生成出来たらいいなと思っていた時期もありました。誰かやってください。 アセンブラが動けばシミュレータを動かしだせます。アセンブラを介さずアセンブリを読んで実行するシミュレータを作った班もあるみたいです。確かにそっちのがデバッグ楽かもしれん……(隣の芝が青いだけの可能性もあります)。

動くシミュレータを作る

やっぱりシミュレータが動かないと始まりません。コンパイラの動作が正しいことを確認するにも、コアの動作が正しいことを確認するにもまずはシミュレータが正しい値を返す必要があります。 今回はrustという言語を用いました。あまり触れたことのない言語(夏学期の課題でオセロのAIを作ったのが最初でした)でしたが、何事もチャレンジということで選びました。きちんとコンパイルエラーを出すいい言語です。 後々の拡張を見据え、なるべくコアみたいに動く(フェッチなどの段階を分割しやすくする)ことを意識しました。これはパイプラインを再現するうえで助かりでした。これはいい考えでしたね。

便利なシミュレータを作る

シミュレータはデバッグに用いますから、その時々のレジスタの値やプログラムカウンタの値などを伝える必要があります。中にはGUIまで作っている班があって凄いなぁという感じです。私にはそこまでできなかった。

結合テストをする

コンパイラ係がfibのコンパイルできるよ!って言ってくれたらそれを動かします。シミュレータがバグってる可能性もあるので、シミュレータ係がデバッグするのがいいと思います。 メモをしていない素朴なfibはfib 30の段階で三千万命令ぐらいになります。rust君は早いので余裕です。ちなみにレイトレは数十億命令ぐらいになるらしいので、遅い言語でシミュレータ書くのはやめといたほうがいいかもしれません。 別にfibをやれと言われることはないのですが、再帰が実装できているかどうかはやはりfibが一番単純でわかりやすいということなのでしょう。そのうちコア係がfibを動かしてくれます。デバッグにこの機能ほしいとか言われたら対応しましょ。

そのうちmandelbrot計算しよ!とかいう話になります。これはfloat演算の結果が正しいかどうかを知るよいテストになります。レイトレでは単精度計算で十分なので単精度でやるんですが、OCamlには単精度浮動小数点はないので、適当にほかの言語で比較しないとコケます。

FPUの実装に合わせたfloat計算をする

シミュレータは実機と完全に同じ動作をする必要があります。なので、例えばFPUの結果が組み込みのfloat演算とほんの少し誤差があるとしても、実機に合わせなければなりません。よって、最終的には組み込みのfloat演算ではなくFPUがやってるようなビット的な計算をする必要があります。FPU係に手伝ってもらいましょう。とはいえ、組み込みでも当分は平気ですので最初は気にせず、FPU係と自分の余裕に合わせましょう。

大体ここまでがやったことです。ここから今やってること、或いはやらなければいけないことです。

パイプラインに手を出している

まだ高速化の段階ではないのに勝手にやっています。シミュレータ係は自分の好きな言語でやっていいので進みが早いことが多い気がします。なので、適当にフォワーディングとかを再現するようなものをつくり、それこそfib30とかならストールとかしながらパイプライン実行できたんですが、そろそろデバッグの季節なので中断してます。

デバッグをする

コンパイラ係がレイトレのプログラムをコンパイルできるようになったと連絡してきたのでデバッグです。この時期のFPUやコア係は忙しいので、シミュレータ係がやるのがよさそうです。シミュレータバグってるかもしんないし。 レイトレのアセンブリは一万行とかあるのでデバッグは大変です。友人は5時間眺めてバグを見つけたとか言ってました。自分もやらなきゃ。

シミュレータ係に向いてる人

シミュレータ係の適性は、「暇さ」です。コア係が要望を言ってきたらすぐに返してあげましょう。彼らは毎回回路に少しの変更をするごとにvivadoからコンパイルの待ち時間禁固15分を課せられています。 後はデバッグする機会が多いです。やっぱりシミュレータのバグが一番直しやすいので、シミュレータ係がデバッグして自身のバグならちゃちゃっと直し、そうでなければ各担当に投げましょう。他の係のバグは結構非自明で詰まることが多いですが、シミュレータ係のバグは大概不注意やtypoな気がします。後言語が自由なのでエラーが見慣れている言語で書けますしね。今触れたように、シミュレータ係の一番の特徴は、使う言語を選べることです。コンパイラ係も自分で1から作れば自由ですが、やはり多くの人は改造を選びそのためにOCamlを使っています。ぜひとも習得したい言語があったらそれでアセンブラとかシミュレータとか書いてみてはいかがでしょうか。でもやっぱ人気はC++とかなのかな。

おわりに

CPU実験、まだ終わってません。絶賛デバッグ中です。なので、この記事も短いですがこのくらいで終わりにします。完動したらまた書くのかな、でも大体書いているような気もします。シミュレータ係の記事ってほんとにないので、役に立つような記事が書けるように未来の私にお願いしときます。

この記事を読んでいる私は、再び一万行のアセンブリへと潜っていきます。