前回までのあらすじ
- 自作PCを作ろう!
- まずメモリを作ったよ!
- ISAを作ったよ!
- アセンブリ言語を作ったよ!
- CPUを作ったよ!
- 任意のプログラムを実行できるようになったよ!
- キーボード入力を受け付けられるようになったよ!(ただし独力ではない)
- 複数桁+複数桁の足し算が行えるようになったよ!
-
CALL命令とRET命令を実装して,関数呼び出しが可能になったよ! - 自作CPU上で動作する自作プログラミング言語をコンパイルするコンパイラを作ったよ!
- 上記コンパイラで,プログラミング言語から機械語への一気通貫が可能になったよ!
- gitで開発環境を整えたよ!
- 自作プログラミング言語が構造体と文字列操作関数に対応したよ!
今回の目標
今回はちょっと横道にそれます.
並行開発ができるようになったので,前回の対応のついでにマルチパイプライン化について対応します.
現在のQurge(自作CPU)はシングルパイプラインです.
フェッチ,チェック(読み込み専用レジスタに書き込もうとしていないかなど),実行がそれぞれ一クロックずつ消費するため,機械語の一命令を実行するのに複数クロック消費します.
そうではなく,実際に使用されているCPUのようにマルチパイプラインに対応することによって処理の高速化を目指します.
ここから本題
マルチパイプラインに対応すると言っても,かなり大規模な修正になるので段階的に対応していきます.
命令実行中に次の命令をフェッチしておく
前述のとおり,現在のCPUは以下を繰り返し行っています.
- フェッチ
- チェック
- 実行
しかし,実行には時間がかかる命令があります.
例えば,割り算やメモリ読み書き命令は一つの命令に対して複数クロック消費します.
そのため,「実行待ちの間に次の命令のフェッチをしておけばいいのでは?」というのがこの対応です.
ただし,実行中にフェッチするだけなので,一命令につき一クロックしか節約できません.
そんなに高速化するわけではないうえ,この時点ではまだマルチパイプラインとは言えません.
また,条件分岐やジャンプ命令がある場合には対応しません.ちょっと複雑になるので.
命令実行中に次の命令のチェックまで行う
前回の変更では,命令実行中に行うのは次の命令のフェッチまででした.
この修正で,次の命令のチェックまで行います.
チェックというのは,書き込み禁止領域に書き込もうとしていないか,読み込み禁止領域を読み込もうとしていないかなどですね.
これで,命令を実行し終わったらすぐに次の命令の実行が行えるようになります.
ただし,以下の命令に関してはその限りではありません.
-
DIVのように,一サイクルで実行が終わらない命令(一サイクルで命令が終わらないので,一サイクルごとに一命令実行とはいかない) - 条件分岐やジャンプ命令(ちょっと複雑になるのでこの時点では対応しない)
分岐やジャンプ命令についても前の命令の実行中にフェッチとチェックするようにする
今までの変更によって,実質的に一クロックで一命令を実行できるようになりました.
ただし制限もあります.
-
DIV命令など,実行に複数クロックかかる命令については一クロックで完結しない - 分岐やジャンプの後の命令は事前にフェッチしていないので,フェッチとチェックからやり直しになる
この修正では二番目を解決します.一番目については後続の命令と同時進行で実行するとかじゃないと解決できません.
フルバージョン
今後の展望
実はまだマルチパイプライン自体は完成していないのですが,別の対応を急ぐためいったん中断してここまでを前編とします.
次の記事ではやっとシェルの実装を行います.