CPU(Central Processing Unit/中央処理装置)とは、機械語の命令に従い、レジスタ・メモリ・次に実行する位置の状態を変える装置です。CPUは「A」という文字や「保存」という目的を理解しているのではありません。決められた0と1の並びを命令として判別し、数値の計算、比較、データ移動、処理位置の変更を繰り返しています。

「取り出す・解釈する・実行する」だけでは、何を取り出し、何が変わったら実行完了なのかが見えません。この記事では、その3語をCPU内部の部品と状態変化へ結び直します。
画面の「Aを保存」とCPUの仕事は、説明の階層が違う
この記事では、テキストエディタでmemo.txtを開き、半角の「A」を入力して保存する場面を最後まで使います。人から見ると「Aを保存した」という1つの操作ですが、CPUに届く「Aを保存」という命令はありません。
テキストエディタは、入力イベントを受け取り、作業中の文字列へAを追加し、保存操作を受けたらOSへ書き込みを依頼します。そのアプリもOSも、最後はCPUが実行できる細かな機械語命令の列として動きます。
| 説明の階層 | 「Aを保存」で起きること | CPUから見えるもの |
|---|---|---|
| 利用者 | memo.txtへAを入力して保存する |
文字やファイルの意味は見えない |
| アプリ | 文字列を更新し、保存処理を呼び出す | アプリを構成する機械語命令とデータ |
| OS | ファイルへの書き込みを組み立てる | OSを構成する機械語命令とデータ |
| CPU | 命令に従って数値やアドレスを処理する | ビット列、レジスタ、メモリアドレス、実行位置 |
CPUが実行する「命令」は、意味の決まったビット列
人が書いたJavaやCなどのソースコードは、そのままCPUへ渡りません。コンパイラや実行環境などを経て、対象CPUの命令セット(ISA:Instruction Set Architecture)に合う機械語命令になります。詳しい橋渡しはコンパイラとインタプリタの違いで解説しています。
1つの機械語命令には、一般に「何をするか」を表すオペコードと、「どの値を使い、どこへ結果を置くか」を表すオペランドの情報が含まれます。命令の長さやビット配置は、x86、Arm、RISC-Vなど命令セットごとに異なります。
| 命令の種類 | 命令が指示すること | 主に変わる状態 |
|---|---|---|
| 演算・論理 | 加算、減算、AND、比較などを行う | レジスタの値 |
| ロード | 指定アドレスのデータを読み込む | メモリからレジスタへ値が移る |
| ストア | レジスタの値を指定アドレスへ書く | メモリ側の値 |
| 分岐・ジャンプ | 条件に応じて別の命令位置へ進む | 次に実行する位置 |
| システム命令 | 例外を発生させるなど、実行環境へ処理を渡す | 制御の流れや動作モード |
RISC-Vの基本命令仕様を例にすると、演算命令はレジスタを読み結果をレジスタへ書き、ロードとストアがレジスタとメモリの間で値を移し、分岐命令が条件に応じて次の命令位置を変えます。CPUが「解釈する」とは、人の意図を理解することではなく、命令中のビット欄を回路が判別し、使うレジスタや演算回路を選ぶことです。
「取り出す・解釈する・実行する」を中身まで分解する
CPUの基本サイクルは、次の命令位置を定め、命令を取得し、命令の種類と材料を判別し、必要な回路で処理し、結果と次の位置を確定する流れです。まず全体を図でつなげます。

1.プログラムカウンタが命令列の位置を示す
実行中のプログラムは、機械語命令の列としてメモリ上に置かれています。CPUは、プログラムカウンタ(PC)と呼ばれる状態を手掛かりに、命令列のどこから取得するかを決めます。
この記事ではPCを「次に取得する命令の位置」として説明します。実際の命令セットでは「現在の命令のアドレス」と定義する場合や、別名を使う場合があります。たとえばx86-64では命令ポインタをRIPと呼び、RISC-Vではpcが現在の命令アドレスを保持すると定義されています。共通する本質は、CPUが命令列のどこを進んでいるかを示す基準であることです。
2.フェッチで、その位置の命令ビットを取得する
CPUはPCが示すアドレスを使い、命令を取得します。これがFetch(フェッチ)です。現代のCPUでは、多くの場合、まずCPUに近い命令キャッシュを調べ、そこになければ下位のキャッシュやメインメモリから取り寄せます。
単純なCPUの説明では、取得した命令を一時保持する場所を命令レジスタ(IR:Instruction Register)と呼びます。この言葉は流れを理解するのに便利ですが、すべての実製品に1個の公開されたIRがある、という意味ではありません。現代CPUでは、命令キューやパイプライン内の保持領域へ複数命令をためる実装が一般的で、IRはそれらを代表させた基本モデルです。
3.デコードで、オペコードとオペランドを判別する
Decode(デコード)では、命令のビット列を欄ごとに分け、「これは加算か、ロードか、分岐か」「どのレジスタを読むか」「結果をどこへ置くか」を判別します。その結果に応じて、レジスタ、ALU、ロード・ストア部などへ制御信号を出します。
4.レジスタから、処理に使う値を取り出す
レジスタはCPUコア内部にある小さな値の保持場所です。演算器が今すぐ使う値、メモリアドレス、計算途中の結果などを置きます。命令に「R1とR2を加えてR3へ」と書かれていれば、CPUはR1とR2のビットを読み、後段の演算回路へ渡します。
メモリはレジスタより大容量ですが、CPUから遠く、取得にはより長い待ち時間がかかります。その差を縮めるため、CPUとメインメモリの間に複数段のキャッシュがあります。レジスタ、キャッシュ、メモリはすべてデータを置けますが、CPUからの距離、容量、管理方法が違います。メインメモリの役割はメモリとはで補えます。
5.ALUまたはロード・ストア部が、命令どおりの変化を起こす
加算、減算、論理演算、比較などは、ALU(Arithmetic Logic Unit/算術論理演算装置)が担う代表的な処理です。メモリアドレスの計算や、レジスタとメモリ階層の間のデータ移動は、ロード・ストア部が担います。実際のCPUには、浮動小数点、ベクトル演算、分岐など用途別の実行ユニットもあります。
大切なのは、Execute(実行)が「何か大きな機能を完成させる」ことではなく、1個または内部で分解された命令が指定した状態変化を進めることです。Aを画面へ追加するだけでも、このような小さな状態変化が多数つながります。
6.結果を書き戻し、PCを次の位置へ進める
演算結果は宛先レジスタへ書き戻され、ストア命令ならメモリ階層へ書き込みが進みます。通常はPCを命令列の次へ進めます。分岐が成立した場合は、PCの基準を分岐先へ変えます。これで次のフェッチ先が決まり、同じ循環が続きます。
つまり「フェッチ・デコード・実行」は3枚の独立したカードではありません。PCが取得位置を決め、デコード結果がレジスタと実行回路を動かし、その結果がレジスタ・メモリ・PCを変え、次のフェッチにつながる循環です。
memo.txtへAを追加する命令を追ってみる
ここでは、キーボードの入力イベントがすでにOSからテキストエディタへ届き、エディタがUTF-8の作業用バッファへAを1バイト追加する、という単純な場面に絞ります。実際のエディタはもっと複雑ですが、CPUの役割は同じです。
次は、動きを見せるための架空の擬似命令です。特定のCPUでそのまま実行できるコードではありません。
LOAD R1, [buffer_end_ptr] ; 追記位置のアドレスをR1へ読む
STORE8 [R1], 0x41 ; Aを表す1バイトをバッファへ置く
ADD R1, R1, 1 ; 次の追記位置を計算する
STORE [buffer_end_ptr], R1 ; 更新した位置をメモリへ戻す
最初のLOADでは、デコーダがロード命令だと判別し、ロード・ストア部がメモリアドレスから値を取得してR1へ置きます。STORE8ではR1が示す位置へ0x41を書きます。ADDではALUがR1へ1を足します。最後のSTOREで、次回の追記位置をメモリへ戻します。
ここまでで変わったのは、実行中のエディタが持つメモリ上の作業データです。まだmemo.txtがストレージへ永続化されたとは限りません。画面の保存ボタンを押すと、別の機械語命令列が実行され、エディタは書き込み対象、バッファのアドレス、長さなどを用意してOSへ処理を依頼します。

CPUがファイル名を理解してSSDへ直接Aを刻むのではありません。CPUはアプリの命令を実行し、システムコール後はOS、ファイルシステム、ドライバの命令も実行します。ファイルとして扱う規則はソフトウェア側にあります。
アプリからOSへ制御が移る詳しい仕組みはシステムコールとは、パスやファイル名を保存領域へ結び付ける仕組みはファイルシステムとはで扱います。CPU記事の境界は、アプリ側でもOS側でも、CPUが実行する対象は機械語命令である、という点までです。
分岐は、PCの行き先を条件で変える命令
テキストエディタは「入力イベントなら文字を追加する」「保存イベントなら書き込みを依頼する」「終了イベントなら閉じる」のように処理を選びます。CPU上では、値を比較し、条件分岐命令によってPCの行き先を変えることで、この選択を実現します。
| 判定結果 | PCの更新 | 次に実行される命令 |
|---|---|---|
| イベント種別が「文字入力」 | 文字追加処理の先頭へ | 作業バッファを更新する命令列 |
| イベント種別が「保存」 | 保存処理の先頭へ | OSへの依頼を準備する命令列 |
| どちらでもない | 次の判定へ | 別のイベントを調べる命令列 |
ループも同じです。PCを前の命令位置へ戻す分岐を使えば、イベント待ちや繰り返し処理になります。CPUが業務上の判断をしているのではなく、比較結果のビットに従って、次の命令アドレスを選んでいます。
クロックとパイプライン:1クロック=1命令ではない
クロックは、CPU内部の回路が段階的に状態を受け渡すための時間の基準です。3GHzなら1秒あたり約30億サイクルですが、「1秒に必ず30億命令を完了する」という意味ではありません。命令によって必要な処理が違い、キャッシュミスや分岐予測の失敗などによる待ちもあるからです。
そこでCPUは、1個の命令がすべて終わるまで次を待つのではなく、工程を重ねます。これがパイプラインです。単純な3段モデルなら、次のように複数命令が同時に別工程を進みます。
| クロック | 取得 | デコード | 実行 |
|---|---|---|---|
| 1 | 命令1 | ― | ― |
| 2 | 命令2 | 命令1 | ― |
| 3 | 命令3 | 命令2 | 命令1 |
| 4 | 命令4 | 命令3 | 命令2 |
これは説明用の単純化です。現代の高性能CPUは工程をさらに細かくし、1サイクルに複数命令を取り込み、独立した命令を複数の実行ユニットへ出すことがあります。分岐では行き先を予測して先の命令を取得し、予測を外したら途中の処理を破棄して正しい位置からやり直します。
アウト・オブ・オーダー実行でも、基本モデルは壊れない
ある命令がメモリ待ちになったとき、後ろにある独立した命令まで止める必要はありません。アウト・オブ・オーダー実行に対応したCPUは、依存関係を確認し、実行可能な後続命令を先に進めます。
ただし、ソフトウェアから見える結果は命令セットの規則やメモリ順序の規則を守る必要があります。多くのCPUは、内部では予測や並べ替えをしても、結果を確定する段階で整合を取ります。したがってフェッチ・デコード・実行は「各命令が時計どおり1列に進む実装図」ではなく、命令を受け取り、指定された状態変化を、CPUの規則に従って確定する論理モデルとして使うのが正確です。
CPUが実行する相手を決めるのはOS
テキストエディタ以外にもブラウザや常駐ソフトが動いているとき、どの処理へCPU時間を渡すかを決めるのはCPU自身ではなく、OSのスケジューラです。OSは実行可能なスレッドを選び、そのスレッドのPCや各レジスタ(スタック位置を示すレジスタを含む)などの実行文脈を、CPUで再開できる状態にします。
| OSが決めること | CPUが行うこと |
|---|---|
| どの実行可能スレッドを、どの論理CPUで動かすか | 選ばれた実行文脈の命令を実行する |
| いつ別スレッドへ切り替えるか | 割り込みや切替処理に必要な機構を提供し、OSの命令を実行する |
| 待機中のスレッドを実行対象から外すか | 実行対象がなければアイドル状態へ入れる |
保存処理がストレージの完了待ちになると、エディタのスレッドはCPUを使わず待機し、OSは別の実行可能スレッドを動かせます。1つの論理CPUでは時間を分けて進め、複数コアがあれば複数の命令列を物理的に並行して実行できます。プロセスとスレッドの違いはプロセスとスレッドとは、OS全体の役割はOSとはでつなげて確認できます。
CPU使用率が示すのは「実行に使われた時間」
CPU使用率は、観測時間のうちCPUがどの程度、スレッドや割り込み処理などの実行に使われたかを見る指標です。高い状態が続けば実行したい処理がCPU能力に近づいている可能性がありますが、瞬間的な100%だけで異常とは決まりません。
反対に、memo.txtの保存が遅くてもCPU使用率が低い場合があります。スレッドがストレージ、ネットワーク、ロックなどを待っていれば、CPUは別処理やアイドルへ移れるためです。性能を見るときは、CPU使用率とともに、実行可能なのに待っているスレッド、I/O待ち、キャッシュミスなど、どこで命令の進行が止まったかを確認します。
ここまでで解消したい5つの誤解
| 誤解 | 正しい捉え方 |
|---|---|
| CPUは文字やプログラムの目的を理解する | 命令形式とビット列に従って状態を変える |
| フェッチ・デコード・実行は3つの独立作業 | PCと状態更新によって次の命令へつながる循環 |
| 計算はメモリ上の値をそのまま行う | レジスタへ値を用意し、ALUなどの実行回路へ渡すのが基本 |
| 保存ボタンを押すとCPUがSSDへ直接書く | CPUはアプリとOSの命令を実行し、I/Oの各層が書き込みを成立させる |
| 1クロックで必ず1命令が終わる | 複数工程が重なり、命令数も待ち時間もCPU設計と処理内容で変わる |
Javaプログラムで見える変数やヒープも、最終的にはCPUが命令を実行して扱います。ただし、Java仮想マシンが管理する論理的な領域とCPUレジスタやキャッシュは同じものではありません。Java固有の続きを知りたい場合はJavaのメモリ管理へ進んでください。
まとめ:CPUとは、命令を状態変化へ変換する装置
memo.txtへAを入力して保存するとき、CPUが理解するのは「A」や「ファイル」ではありません。PCが示す位置から命令ビットを取得し、デコーダが使うレジスタと回路を選び、ALUやロード・ストア部が値を変え、結果と次のPCを確定します。この小さな循環を、アプリとOSの膨大な命令について高速に重ねた結果が、画面で見る「Aを保存できた」という動作です。
