命令セットアーキテクチャ ─ CISC/RISCとマイクロオペ
なぜx86は遅くないのか。複雑なCISC命令を内部で固定長マイクロオペに割り、実装はRISC風に動く。ISAという抽象境界と中身の乖離を原理から掴めます。
- 1.x86のCISC命令はデコード段で固定長のマイクロオペ(μop)へ分解され、内部のアウトオブオーダ実行はRISCコアと同じデータフロー駆動で動く。ISAの複雑さは実装の複雑さと切り離されている。
- 2.Arm/RISC-Vは固定長命令とロードストア型を選び、デコードを単純化してパイプラインと並列デコードを楽にする。命令密度ではCISCに譲るが実装の素直さで返す。
- 3.ABIはレジスタの役割・引数渡し・スタック規約を定め、ISAの上に互換の境界を引く。ISAは抽象、μopやマイクロアーキテクチャは実装で、両者の乖離こそ設計判断の核心。
ISAは契約であって実装ではない
**命令セットアーキテクチャ(ISA)**は、ソフトウェアとハードウェアの間に引かれた契約です。どんな命令があり、レジスタは何本で、メモリをどうアドレス指定し、例外がどう振る舞うか――この約束さえ守られていれば、同じバイナリはどの実装でも同じ結果を返します。重要なのは、ISAが「何ができるか」を規定するだけで「どう実現するか」には踏み込まない点です。命令の見た目が複雑でも、内部の回路がそのとおり複雑である必要はありません。
この抽象境界と実装の乖離こそ、現代プロセッサ設計の中心的な判断です。x86は1978年の8086から続く複雑な命令体系を背負いながら、内部では後述のとおり単純な命令へ砕いて実行します。古いソフトウェア資産を守る契約は維持しつつ、中身は時代ごとに作り替えてきたわけです。
CISCとRISCはどこで分かれたか
歴史的に二つの設計思想が対立しました。CISC(Complex Instruction Set Computer)は、1命令で多くの仕事をこなす豊かな命令を志向します。メモリ上の値を直接加算するような複合命令を備え、命令数を減らしてプログラムを短くします。代表がx86です。
RISC(Reduced Instruction Set Computer)は逆に、単純な命令だけを高速に回す方を選びます。代表はArmとRISC-Vです。両者の違いは命令の「数」より、次の設計選択に表れます。
| 観点 | CISC(x86) | RISC(Arm / RISC-V) |
|---|---|---|
| 命令長 | 可変長(1〜15バイト) | 固定長(多くは4バイト) |
| メモリ参照 | 多くの命令が直接メモリを操作 | ロード/ストア命令だけがメモリに触れる |
| 演算オペランド | メモリでもレジスタでも可 | レジスタ同士のみ |
| アドレッシング | 多様で複雑 | 少数で規則的 |
| デコード | 複雑・段数が多い | 単純・並列化しやすい |
RISCの核心はロードストアアーキテクチャです。演算命令はレジスタ上の値しか扱えず、メモリとの往復は専用のロード命令とストア命令に限定されます。これにより演算命令の振る舞いが揃い、デコードと実行が規則的になります。固定長と合わせて、命令の切れ目を探さずに済むので、複数命令を同時にデコードするのも容易です。
可変長のCISCは、よく使う操作を短いバイト列に詰められるため命令密度が高く、同じ処理をより少ないバイト数で表せます。これは命令キャッシュの利き方に効きます。一方の固定長RISCは、単純な操作にも4バイトを使うので密度では劣りますが、デコードの単純さで取り返します。「密度を取るか、デコードの素直さを取るか」が分岐点でした。
x86が内部でRISC化する仕組み
ところが現代では、この対立は見た目ほど鋭くありません。鍵は**マイクロオペレーション(μop, マイクロオペ)**です。
x86のような可変長CISC命令は、デコード段で1個以上の固定長のμopへ分解されます。たとえば「メモリの値とレジスタを加算してメモリへ書き戻す」命令は、内部では「ロード→加算→ストア」という複数のμopに割られます。このμopこそがRISC風の単純命令で、これ以降のパイプラインはμopだけを相手にします。つまりx86チップの実行コアは、実質的に内部RISCマシンです。
x86命令 デコーダ 内部μop列(固定長・RISC風)
add [mem], eax ─────────► load t1 <- [mem]
(CISC・可変長) add t1 <- t1 + eax
store [mem] <- t1
分解されたμopは、アウトオブオーダ実行のエンジンにそのまま流れます。μopにはレジスタリネーミングが施され、オペランドの揃ったものから順不同で発行され、リオーダバッファ(ROB)でプログラム順にコミットされます。ここはArmの実装と本質的に同じ仕組みです。
デコードはx86では重い処理なので、近年のチップは一度割ったμopをキャッシュし、同じ命令の再デコードを省きます。逆に、比較命令と分岐命令のように頻出する組を1個のμopへ融合(マクロ融合・マイクロ融合)して実行資源を節約する最適化もあります。割る方向と束ねる方向、両方でデコード境界を調整しているわけです。
固定長で素直なArm/RISC-Vのデコードは、x86のような重いデコーダを必要としません。この差はフロントエンドの面積と電力に効きますが、実行コアより後ろ(バックエンド)の作りは両陣営で収束しています。だからこそ「ISAがCISCかRISCか」だけで性能を語れなくなりました。実装が決めるのです。
固定長と整列が効くところ
RISCの固定長は、メモリ参照の規則性にもつながります。命令そのものがアラインされた境界に並ぶため、命令フェッチが単純になり、命令パイプラインの前段でストールを生みにくくなります。可変長のx86は、ある命令の長さを解かないと次の命令の開始位置がわからない――この逐次依存が並列デコードの障害になり、それを越えるための工夫がデコーダの複雑さに直結します。
ロードストア型は、メモリアクセスの発生箇所を明示する効果もあります。メモリに触れるのはロード命令とストア命令だけなので、キャッシュの原理が効くアクセスがどの命令かを実装が把握しやすく、スケジューリングや投機の判断がしやすくなります。
ABI ─ ISAの上に引くもう一段の契約
ISAは命令とレジスタを定義しますが、「レジスタをどんな役割で使い、関数へ引数をどう渡し、戻り値をどこへ置くか」までは規定しません。これを定めるのがABI(Application Binary Interface)であり、**呼び出し規約(calling convention)**です。
| 項目 | 内容 |
|---|---|
| 引数渡し | 最初の数個はレジスタ、残りはスタック(規約で本数が決まる) |
| 戻り値 | 決められたレジスタに置く |
| caller-saved | 呼び出し側が退避責任を持つレジスタ(呼ばれた側が壊してよい) |
| callee-saved | 呼ばれた側が退避・復元する責任を持つレジスタ |
| スタック整列 | 呼び出し時点でスタックポインタを所定の境界に揃える |
ABIが固定されているからこそ、別々にコンパイルされたオブジェクトや、C以外の言語で書かれた関数同士がリンクして正しく呼び合えます。同じArm ISAでもOSやプラットフォームでABIが違えば、レジスタの役割分担が変わりバイナリ互換は成り立ちません。ISAは命令の意味の境界、ABIは関数の呼び出しの境界――抽象の層が二段に分かれています。
「同じISA」はバイナリが動く保証ですが、性能が同じ保証ではありません。同一のx86バイナリでも、μopへの割り方・実行ユニットの数・キャッシュ構成といったマイクロアーキテクチャが世代ごとに違えば、速度は大きく変わります。逆にRISC-Vのように拡張命令がオプション化されたISAでは、ある拡張を前提にコンパイルしたバイナリが、その拡張を持たない実装では動かないことに注意が必要です。
まとめ
- ISAはソフトとハードの契約で「何ができるか」を定め、「どう実現するか」には踏み込まない。この抽象境界と実装の乖離が設計判断の核心になる。
- **CISC(x86)**は可変長・メモリ直接操作で命令密度を取り、**RISC(Arm/RISC-V)**は固定長・ロードストア型でデコードの素直さを取る、という選択の違いが本質。
- x86はデコード段で命令を固定長μopへ割り、内部のアウトオブオーダ実行はRISC風に動く。実行コアの作りは両陣営で収束し、性能は実装が決める。
- ABI/呼び出し規約はISAの上にレジスタの役割と引数渡しの境界を引き、別々にビルドされたコードのリンクと互換を成立させる。
CPU/メモリ/ディスク Article
命令セットアーキテクチャ ─ CISC/RISCとマイクロオペを実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
ISA
比較で見る軸
難易度: advanced / カテゴリ: CPU/メモリ/ディスク / タグ数: 6
導入後に効く点
Arm/RISC-Vは固定長命令とロードストア型を選び、デコードを単純化してパイプラインと並列デコードを楽にする。命令密度ではCISCに譲るが実装の素直さで返す。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- CPU/メモリ/ディスク
- タグ数
- 6
判断チェックリスト
- 自社の用途が「ISA / CISC」に近いか確認する。
- 強みである「x86のCISC命令はデコード段で固定長のマイクロオペ(μop)へ分解され、内部のアウトオブオーダ実行はRISCコアと同じデータフロー駆動で動く。ISAの複雑さは実装の複雑さと切り離されている。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。