CPU 実験・振り返り(コア係視点)
Table of Contents
- 1 はじめに
- 2 班内の役割分担
- 2.1 コア係
- 2.2 FPU・メモリ係
- 2.3 シミュレータ係
- 2.4 コンパイラ係
- 3 時系列
- 3.1 開始前
- 3.2 授業期間中(10月 - 1 月前半)
- 3.2.1 第 1 週 (10/7-10/13)
- 3.2.2 第 2 週 (10/14-10/20)
- 3.2.3 第 3-4 週 (10/21-11/3)
- 3.2.4 第 5 週 (11/4-11/10)
- 3.2.5 第 6 週 (11/11-11/17)
- 3.2.6 第 7 週 (11/18-12/1)
- 3.2.7 第 8 週 (12/2-12/8)
- 3.2.8 第 9 週 (12/9-12/15)
- 3.2.9 第 10 週 (12/16-12/22)
- 3.2.10 第 11 週 (12/23-1/5)
- 3.2.11 第 12 週 (1/6-1/12)
- 3.3 試験期間中(1 月後半 - 2 月頭)
- 3.4 春休み(2 月)
- 3.5 追い込み期(3 月)
- 3.5.1 実機完動 (2/26-3/4)
- 3.5.2 パイプライン構造の見直し (3/4-3/7)
- 3.5.3 メモリモジュールなどの見直し (3/7-3/8)
- 3.5.4 FPU の見直し・小手先のテクニック (3/9)
- 3.5.5 直前追い込み (3/10 AM)
- 4 結果
- 4.1 ハードウェアの仕様
- 4.2 実行速度など
- 5 IS >=26er へ伝えたいこと
- 6 感想
- 7 他の人の記事

はじめに
IS25er*1の sqrt10 です.CPU 実験*2の最終発表会が 3/10 に終わりましたので,その振り返りをしていきます.本当はこの記事は最終発表会翌日の 3/11 には書き上げていたのですが,不慮の事故 によりデータが飛びました… ということで若干遠くなってしまった記憶を呼び覚まし書いていきます.
そもそも CPU 実験とはということを簡単に説明します.詳細は 学科パンフレット に譲りますが,次のように書いてあります:
3学年のAセメスターになると、『プロセッサ・コンパイラ実験』——通称「CPU実験」が始まり、3~4人の各チームに、FPGA基板と道具がいくつか渡されます。ミッションは「半年かけてできるだけ速いコンピュータを作れ」。それから翌年3月の発表会までに、課題のCGプログラムが動くよう、独自のCPUやコンパイラなどをイチから設計・製作します。
なんと,実験の内容はこれだけです.これ以上の説明はほとんどありません.3S までに学んだ知識を総動員し,字義通り全てをイチから開発していきます.この「課題の CG プログラム」というのが min-rt で,その実行結果がトップの画像です*3.同パンフレットには「仕組みを知る早道は作ってみること」とありますが,「急がば回れ Lv.255」のような感じです.この実験が終われば他のどの方法よりも深くプロセッサについて理解できるという点においては確かに早道ですが,その道のりは決して短くはない,ということはここに記しておきます.
班内の役割分担
先のパンフレットの記述の通り,班は原則 4 人で行われる.学科の人数によっては 3 人班や 5 人班ができたりもするようだが,今年度は 32 人だったため 4 人班が 8 個できた.4 人それぞれに役割が与えられているので,それぞれについて班分けの資料を引用しつつ紹介する.
コア係
- グループで策定した命令セットアーキテクチャに基づくプロセッサをハードウェア記述言語 (HDL) で開発する。
- FPU・メモリ係と連携して、FPGAシステム全体の開発を進める。
筆者はコア係だったので,本記事もコア係視点となる.基本的には (System) Verilog などの HDL (Hardware Description Language) を用いて,FPGA (Field Programmable Gate Array) 上に回路を構築していく係である.3S セメスター『ハードウエア実験』の内容をさらに進化させたような感じなので,コア係適性はそこである程度測れる.プロセッサの開発という点において全ての責任を負うので,学べることは非常に多い一方,他の 3 人がどれだけ頑張ろうとコア係が崩れれば完動はない.
FPU・メモリ係
- 浮動小数点演算回路をハードウェア記述言語 (HDL) で開発する。
- FPGA内部のブロックRAMとFPGA外部のDRAMを組み合わせてキャッシュメモリを含むメモリシステムをHDLで開発する。
- コア係と連携して、FPGAシステム全体の開発を進める。
コア係の開発内容から FPU(浮動小数点演算回路)とメモリのモジュールを委託された形になっている.こちらも基本 HDL だけを使っていくが,開発の自由度はそこまで高くはない.しかしながら,ハードウェア側で最も劇的に高速化できるのがこれら FPU とメモリであり,高速化に貢献するという意味では FPU・メモリ係のほうが大きい役割を果たす.なお,メモリではキャッシュを用いることが必須となっている.
シミュレータ係
- グループで策定した命令セットアーキテクチャに基づくプロセッサの命令セットシミュレータ (ISS) を先行して開発し、ハードウェアおよびコンパイラの開発を支援する。
- FPU・メモリ係が開発するメモリシステムの振る舞いをシミュレーションする機能(タイミングモデル)を開発し、プログラム実行時間を推定可能なプロセッサシミュレータを開発する。
班での開発という観点では前段の要件が重要である.まずはコンパイラが正しいコードを吐くことを確認するために,シミュレータ上で正しく動くことを確認する*4.その後そのコードを基にコア係の作る回路のデバッグを行っていくため,バグの原因がコンパイラにあるのかコアにあるのかを切り分けるのに重要である.また,gdb のようなデバッガ・プロファイラを作成し,デバッグの高速化や高速化へのヒントも提供する.ただそれだとあまり面白くないからか後段の要件が単位要件として追加されている.開発の自由度は非常に高く,好きな言語で開発できる*5.またハードウェアのこともソフトウェアのことも幅広く理解している必要がある.
また,これは非公式ではあるがシミュレータ係がアセンブラを開発することが通例である.
コンパイラ係
- MinCamlで記述された課題プログラムから、グループで策定した命令セットアーキテクチャに基づくプロセッサで動作する、実行バイナリを生成するコンパイラを開発する。
- 必要に応じてライブラリ等の開発を行う。
基本的には MinCaml という OCaml のサブセット言語から,自らの ISA に対応するアセンブリを吐くコンパイラを作ることが仕事である.こちらも 3S セメスター『関数・論理型プログラミング実験』である程度コンパイラを作るため,そこで適性を測れる.コンパイラについてはコンパイラ実験のほうである程度(直接的には使えない課題もあるにせよ)課題が出され,また既存の MinCaml のコンパイラでも SPARC, PowerPC, x86 にコンパイルは可能であることから最低要件を満たすまでの道のりは非常に整備されている.また,高速化という観点では命令数がほぼそのまま線形に実行時間に影響を与える上に,他の係との干渉もあまりないので比較的やりやすいように思われる.
時系列
以下,CPU 実験期間中のできごとや進捗などを時系列に沿って紹介する.10 月に A セメスターが始まり,最終発表会は 3/10 だった(例年より遅かった模様).なお,週数の表記については発表会の回数基準のため,暦とは一致しない.
開始前
TSG(筆者の所属するコンピュータ系サークル)の先輩などからなんとなくの情報を仕入れる.初回授業の 1 週間ほど前に班分けの希望アンケートが流れる.もともと筆者はものづくりが好きで,ハードウエア実験も楽しかったことからハード系を志望.どうせなら CPU のこと丸ごと理解したい,ということで第 1 希望をコア係,第 2 希望を FPU・メモリ係に.また 3S セメスターでコンパイラ適性はないことが分かったので,第 3 希望にはシミュレータ係を入れて提出.
授業期間中(10月 - 1 月前半)
第 1 週 (10/7-10/13)
班分けが初回授業で発表される.第 1 希望がコア係で 2 人被ったが,もう 1 人はそこまでコア係に強い希望はないということで筆者がコア係に.他の係はすんなり決まる.初回課題として「線表を作れ」「ISA を作れ」というのがあったので,ガバガバ線表と,MIPS ベースの ISA を作る.
FPGA が配られたので,いわゆる「L チカ」として 7 セグのモジュールを整備した.これは最初から最後まで使ったので,整備しておくと良いと思う.機械語をレバーで入力していく ENIAC みたいなとても簡易的な CPU を組んでみた.
第 2 週 (10/14-10/20)
3S の『計算機構成論』の授業資料や教科書を読み,マルチサイクルプロセッサについて理解する.またパイプラインプロセッサについても絵を描いて理解する.
併せて Linter の整備を行う.自分は Neovim に mason で svlangserver を入れ,verilator を用いた.これも早めにやって良かったことの一つである.
第 3-4 週 (10/21-11/3)
パイプラインプロセッサを verilog で実際に書いてみた.デバッグをしようと思ったが謎の高熱を発症してしまい,しばらく寝込む.回復後,簡単なプログラム(ハザードがあまりないもの)で動作を確認.
第 5 週 (11/4-11/10)
FPU(と思しきもの)が来たので,組み込む.併せて小数命令への対応を始める.
第 6 週 (11/11-11/17)
コンパイラ係の出力したコードを動かしてみるが,動かず.ハザードユニットのデバッグを行う.
第 7 週 (11/18-12/1)
引き続き様々なバグを潰す.
第 8 週 (12/2-12/8)
ついにデバッグがあらかた完了.コンパイラ係の吐く fib のコードが動いた.あとは小数命令を確認していきつつ,メモリが来れば,という感じになった.
デバッグに飽きたので,GShare 分岐予測器を作成した.少々バグを埋めこんだ.結局この適当な GShare 分岐予測器をほとんど変えることなく最後まで使った.
第 9 週 (12/9-12/15)
ここでシミュ完動.8 班中 4 番目の早さ.浮動小数点数の演算にはバグがあったので修正していく.
第 10 週 (12/16-12/22)
基本的に FPU とメモリ待ちに.FPU のテストベンチを作成したり,FPU・メモリ係と FPU の信号に関する齟齬を修正したりする.
第 11 週 (12/23-1/5)
そういえば,と重い腰を上げて UART のモジュールを使う.
第 12 週 (1/6-1/12)
メモリが来たが,繋がらなかった.
試験期間中(1 月後半 - 2 月頭)
試験に注力していたため,進捗なし.
春休み(2 月)
FPU もメモリも来ないかバグっているか実用的でないか,という状態で 1 ヶ月経過した.最終発表会まで 2 週間となったところで流石に焦りを感じ,最悪のケースでは他の班からもらったメモリと,AI が書いた FPU で完動させることを決意.
追い込み期(3 月)
実機完動 (2/26-3/4)
などというプレッシャーを FPU・メモリ係に与えたらようやくまともに動くメモリと FPU が届いた.この時点で最終発表会 12 日前.全ての可処分時間を CPU 実験に注ぎ込み,ひたすらデバッグ.
コンパイラ係のレポジトリに無断で main 直 push するなどという事件(?)もあったが,3/4 に無事完動.当然(最終発表会までに)完動した班の中では最も遅い完動となった.
パイプライン構造の見直し (3/4-3/7)
実機完動はしたものの,とうていコンテストに出せる代物ではなかったので高速化に励む.ようやく CPU 実験が始まったなという感じに.もう FPU やメモリの構造を変える大きな変更をする時間はない.パイプラインの段数を増やし,クリティカルパスに余裕を持たせることに.そこそこ大きな改造だったため,2 日間再び完動から遠ざかる.3/7 21:22 に無事新しいパイプラインで完動.
メモリモジュールなどの見直し (3/7-3/8)
メモリモジュールのラッパについて,不要な stall が発生していたり,UART を非同期ではなく同期で行っていたりといった無駄があったので修正.これも多少バグったが 3/8 23:26 に再び完動.残るは丸 1 日に.
FPU の見直し・小手先のテクニック (3/9)
FPU に無駄が多いことを発見.さらに,実はテストベンチが通っていないものがあることも発見*6.このあたりを修正したりさせたりする.また,もう本質的な改善をする時間はなかったため小手先のテクニックを使い周波数を向上させる.
直前追い込み (3/10 AM)
最終発表会前日夜から当日朝にかけて徹夜で作業.主にシミュレータ係の単位要件を満たすことを行った.並行して周波数を 0.1 MHz でも向上させようとする.シミュレータと実機の出力が異なる問題については fmul が異なることによっていた.また,シミュレータの実行時間予測が異なる問題については,メモリ係が stall 数のカウントを誤っていることが原因であった.なんとか発表会当日 8:58 に開発が終了し,50 分ほど仮眠を取って最終発表会へ.
結果
ハードウェアの仕様
- 動作周波数 98.5 MHz (98.46154 MHz)
- 32 bit アーキテクチャ(MIPS ベース)
- 6 段パイプライン (IF, ID, RA, EX, MA, WB)
- 命令メモリ約 64 KiB(全て BRAM)
- マルチサイクル FPU
- GShare 分岐予測器
- 非同期 UART (921,600 baud)
実行速度など
以下,全て 256x256 の min-rt の結果.なお,8 班のうち最終発表会には 7 班が完動した.順位はその中のもの.
- 実行時間:130.3660 sec.(2 位)
- 命令数:4,818,424,937(3 位?)
- サイクル数:12,774,451,650
- CPI = 2.651, IPC = 0.3772
IS >=26er へ伝えたいこと
To be written...
感想
To be written...