- ブラウザURL入力
- DNS名前→IP
- ルータ経路選択
- ロードバランサ振り分け
- Nginx受け口
- アプリ処理今ここ
- DB保存
前回、論理回路を並べると計算ができることを見ました。今回はその計算装置に「次は何をするか」を指示する仕組み、CPUの動作サイクルを見ます。
まず結論
CPUは「命令を取ってくる(フェッチ)→ 何の命令か読み解く(デコード)→ 実行する」を繰り返しています。
ただしこれは、すべての命令が論理的に通らねばならない段取りであって、実物のCPUが3つの段階でできているという意味ではありません。最近のx86のCPUは同じ処理を14〜19段程度に細かく刻み、しかも複数の命令を同時に流しています。
現代のPCに入っているCPUは、1つの命令を完全に終えてから次の命令に取りかかるでしょうか。
当てることが目的ではありません。外した予測ほど記憶に残るので、直感で選んでください。
CPUがひたすら繰り返している3つのこと
前回、論理回路を並べると足し算ができることを見ました。しかし回路だけでは、いつ何を計算するのかが決まりません。それを決めるのがCPUの動作サイクルです。
CPUは、電源が入っている間ずっと、次の3つを繰り返しています。
- フェッチ(取ってくる) — メモリから次の命令を読み出す
- デコード(読み解く) — その0と1の並びが何の命令か判定する
- 実行 — 実際に計算したり、メモリに書いたりする
第1レッスンで「プログラムはデータと同じメモリに置かれている」と学びました。フェッチとは、そのメモリから命令を1つ取ってくる作業です。CPUは「次にどこから取ってくるか」をプログラムカウンタという専用の記憶場所に持っていて、命令を1つ取るたびにそれを進めます。
1つの命令が処理される流れ
具体的に「レジスタAとレジスタBを足してCに入れる」という命令が処理される様子を追います。
- ・「実行」で使われるのが、前回組み立てた加算回路(ALU)
- ・この繰り返しだけで、あらゆるプログラムが動いている
デコードが何をしているかというと、命令の0と1の並びを、意味のある部品に切り分けているだけです。「先頭の数ビットは操作の種類」「次の数ビットは対象のレジスタ番号」というように、あらかじめ決められた区切りで読み取ります。この区切り方の取り決めが命令セット(ISA)です。
CPUは「次にどの命令を実行するか」をどうやって覚えていますか。
ただし、3段階というのは粗い見取り図
ここで正直に補足しておきます。「CPUはフェッチ・デコード・実行の3段階でできている」という説明は、正確ではありません。
3つの段取りはどの命令も必ず通ります。その意味で嘘ではありません。しかし実物のCPUは、この処理をもっと細かく刻んでいます。
CPU 段数 備考MIPS R2000/R3000 5 教科書に出る古典的な5段Intel Skylake世代 14〜19 デコード済み再利用で14、命令から読むと19Intel Pentium 4 20 深すぎて後に方針転換Pentium 4 Prescott 31 歴代でも極端に深い
なぜ細かく刻むのかは次回のパイプラインで扱います。ここで押さえてほしいのは、3段階は「論理的にこれだけのことが起きる」という見取り図であって、回路の個数ではないということです。
そしてもう一点。段数を決めているのは命令セットではなく、各CPUの実装(マイクロアーキテクチャ)です。 同じx86-64という命令セットでも、Pentium 4は20段、Skylakeは14〜19段です。「x86は何段」という問いには答えがなく、「どの世代のx86か」で決まります。
デコードが重い、という事情
上の表で、Skylakeが「14〜19段」と幅を持っているのが気になったかもしれません。この5段ぶんの差は、デコードの費用です。
x86の命令は長さが固定ではありません。1バイトで済む命令もあれば、15バイト近くになる命令もあります。どこまでが1つの命令なのかを読み解くだけで手間がかかり、さらにCPU内部で扱いやすい単純な操作(µop)に分解する必要があります。
命令セット 命令の長さ デコードの負担x86-64 可変(1〜15バイト) 重い。µopへの分解が必要ARM64 固定(4バイト) 軽いRISC-V 固定(4バイト中心) 軽い
そのためSkylakeは、一度デコードした結果をµopキャッシュに貯めておき、同じ命令を再び実行するときはデコードを飛ばします。これが「14段」の経路です。デコードから始める場合が「19段」です。
ARM64やRISC-Vが命令長を固定にしているのは、このデコードの負担を根本から減らすためです。
「このCPUはx86なので、パイプラインは20段です」という説明は妥当ですか。
この章のまとめ
- CPUは「フェッチ(取ってくる)→ デコード(読み解く)→ 実行」を延々と繰り返している。
- 次に実行する命令の場所は、プログラムカウンタが保持している。分岐はこの値の書き換えで実現される。
- 3段階は論理的な段取りの見取り図。最近のx86のCPUは14〜19段程度に細かく刻んでいる。
- 段数を決めるのは命令セットではなく実装(マイクロアーキテクチャ)。同じx86でも世代で全く違う。
- x86は命令長が可変なのでデコードが重く、µopへの分解が必要。ARM64やRISC-Vは命令長を固定してこれを避けている。
自分の現場で確かめる
読んだだけでは身につきません。手元の環境で実際に見てみてください。
理解度チェック
読んだ直後は「分かった」と感じやすいものです。実際に解いて確かめてください。
「フェッチ・デコード・実行」という3段階の説明について、最も正確なのはどれですか。
用語集(5語)
- フェッチ / デコード / 実行
- 命令を取り出す・何の命令か読み解く・実際に処理する、という命令処理の3つの論理的段取り。実物のCPUはこれをより細かい段に分割している。
- クロック
- CPUの動作の刻み。3.0GHzなら1秒間に30億回の刻み。1回の刻みを1サイクルと呼び、CPUの速さを測る基本単位。
- 命令セット (ISA)
- そのCPUがどんな命令を理解するかの取り決め。x86-64、ARM64、RISC-Vなど。「何ができるか」の仕様。
- マイクロアーキテクチャ
- 命令セットを実際にどう実装するかの設計。SkylakeやZen 3など。同じ命令セットでも実装は世代ごとに全く違う。パイプライン段数はこちらで決まる。
- µop (マイクロオペレーション)
- x86の複雑な命令を、CPU内部で扱いやすい単純な操作に分解したもの。デコード段でこの変換が行われる。