LabHub

ブログ

コンピュータアーキテクチャの現代 — CPU Pipeline・Out-of-Order・Cache・Branch Prediction・Meltdown・Apple Silicon・ARM・RISC-V・SIMD・GPU 深層ガイド (2025)

한국어English日本語

2026年のバックエンドエンジニアが CPU 内部を知るべき理由

Rust で書いたのに C より遅いことがある。HashMap を使ったのに Vec<(K,V)> 線形探索のほうが速い瞬間がある。if ひとつで10倍遅くなる。なぜ M1 が同世代の Intel を超えたのか。答えはすべて CPU の内部で起きていることを理解すれば自明になる。ソフトウェアはハードウェアの上で動く。CPU はあなたが a + b と書いたコードを その順序通りに実行しない。Pipeline、Cache、Branch Predictor、メモリコントローラが見えない所で介入する。本稿はその内部を開く。

2018年の Meltdown/Spectre 以降、「CPU はもはやブラックボックスではない」が業界の常識になった。Apple Silicon M1 (2020) は「RISC ARM が x86 を正面から超え得ること」を証明し、AWS Graviton4・NVIDIA Grace・Ampere Altra はクラウドコスト30%削減を現実にした。RISC-V は Western Digital・SiFive・Tenstorrent・Meta がシリコンを焼く段階だ。GPU は H100/H200 を越え B100/B200 Blackwell (2024)・GB300 (2025) が LLM 経済を支配している。ソフトウェアエンジニアがこの流れを避ける道はもう無い。

本稿は先に書いた Rust 深層ガイドと接続する。Rust が zero-cost abstraction を宣言できる理由は、結局 CPU フレンドリーなコードにコンパイルされるからで、その「CPU フレンドリー」の正体をここで解剖する。

第1部. Transistor から Instruction まで — あなたの if 文が本当にやっていること

1.1 Von Neumann から現代 CPU までの30秒

1945年に Von Neumann が提案した構造は今も 論理的には 変わっていない。メモリにコードとデータが共存し、CPU が順次読み実行する。しかし 物理的には 大変革が起きた。

一枚のチップに 200億個超の Transistor が入るのに、我々が書くコードは依然 a + b だ。その間を埋めるのが現代 CPU の設計。

1.2 命令実行の5ステージ (実は20)

教科書の RISC Pipeline 5段。

  1. Fetch — メモリから命令を読む
  2. Decode — 何をせよかを解釈
  3. Execute — 実際の演算
  4. Memory Access — 必要なら read/write
  5. Write Back — 結果を Register に保存

現代 x86 (Golden Cove, Zen 4) ではこれが 14から20段 に細分化されている。各ステージを短くしてクロックを上げるためだ。ただし Pipeline が長いほど Branch Prediction ミスのコストが増大する。

1.3 Superscalar — 1サイクル4から8命令

単一命令 Pipeline は1990年代で終わった。今は1クロックで複数命令を発行する。

重要な理由: あなたの C/Rust コードの IPC (Instructions Per Cycle) が3から4なら、CPU は並列に多くの演算を回している。IPC が0.5なら Pipeline を殺している (Branch miss, Cache miss, 依存チェーン) 何かがある。

第2部. Out-of-Order Execution — CPU はあなたのコードを並べ替える

2.1 なぜ並べ替えるか

int a = load_from_memory(&x);  // 100サイクルかかる miss
int b = 2 + 2;                  // 1サイクル

In-order CPU は1行目が終わるまで b を始められない。Out-of-Order CPU は b を先に実行し、a が到着したら合流する。命令間に依存が無ければ 順序不問で実行する。

2.2 ROB, RS, Register Renaming

「コード上の RAX が実際は192個の Physical Register の一つ」にマップされるため false dependency が消える。Apple M3 の ROB は約700エントリ、Zen 5 は約480。この値が大きいほど先を見て並べ替えられる。

2.3 Speculative Execution — 未来を先に生きる

Branch Prediction → 片方を 仮定 して実行 → 当たれば得、外れれば rollback。これを誤設計した結果が2018年の Spectre/Meltdown (第4部)。

第3部. Cache 階層 — なぜ配列が linked list に勝つのか

3.1 メモリ階層の現実

2025年基準の概算 (x86 P-core、上ほど速い)。

階層容量レイテンシスループット
Register~4000サイクルper-op
L1d48から80KB4から5サイクル3から4 load/cycle
L22から3MB12から15サイクル1 load/cycle
L332から96MB40から50サイクルshared
DRAM32から512GB200から300サイクル50から100 GB/s
NVMeTB級10から100us7から14 GB/s
Network無限大100us以上10から100 Gb/s

Register と DRAM の差は 約100倍。Cache はこの溝を埋める装置。

3.2 Cache Line — Cache の最小単位は64バイト

CPU は1バイト読むだけで64バイト (Apple Silicon は128) を丸ごと持ってくる。これが「配列が linked list に勝つ最大の理由」。

1要素5サイクル vs 100サイクル、つまり 20倍差

3.3 Prefetch — CPU が未来を準備する

Hardware Prefetcher はアクセスパターンを検出し L1/L2 へ事前引き込み。線形ストライド (a[0], a[1], a[2]...) は完璧に検出、複雑なポインタ追跡は失敗。ソフトウェア側は __builtin_prefetch(ptr) (GCC/Clang) でヒント。

3.4 False Sharing — 64バイトの地獄

2スレッドが同じ Cache Line 上の別変数を書くと、MESI コヒーレンシプロトコルが Line 全体を ping-pong する。性能10倍低下の最頻症状。

#[repr(align(64))]
struct PaddedCounter(AtomicU64);

64バイト整列で分離すると消える。

3.5 Data-Oriented Design — ゲームエンジンが見つけた真実

OOP の Entity { name, pos, vel, hp, ... } は Cache にとって悪夢。update_positions が必要とするのは posvel だけなのに namehp が Cache Line を汚染する。ECS (Entity-Component-System) と SoA (Struct-of-Arrays) がこれを構造的に解く。

// AoS: Entity entities[N]  -> Cache 浪費
// SoA: float xs[N], ys[N], vxs[N], vys[N]  -> 純粋な積載

Unity DOTS, Unreal Mass Entity, Bevy ECS がこの設計。

第4部. Branch Prediction — 分岐が10倍遅くなる瞬間

4.1 なぜ予測が必要か

Pipeline 15段なら if 分岐に出会った瞬間「どちらへ進むか不明」。CPU は停止せず 片方を当てずっぽう で続行。当たればロスなし、外れれば15サイクル浪費。

4.2 2-bit Saturating Counter から TAGE まで

Stack Overflow の有名な質問「なぜソート済み配列のほうが速いか」の答えがこれ。ソート済みは if 分岐が予測可能で正解率100%近く、ランダムは50%。

4.3 Branchless プログラミング

ホットループから分岐を除去すれば予測ミスコストが0になる。

// branch
int max = a > b ? a : b;

// branchless (CMOV)
int max = b ^ ((a ^ b) & -(a > b));

Rust/LLVM は単純な三項演算子なら cmov に自動コンパイル。複雑になれば SIMD で分岐ごとベクトル化。

第5部. 2018年以後 — Meltdown, Spectre, MDS, Zenbleed

5.1 Meltdown (Intel)

ユーザーモードから Kernel メモリを投機的に読み、Cache 状態差から値を推定。Intel CPU が権限チェックよりデータロードを先行するバグ。KPTI (Kernel Page Table Isolation) パッチで5から30%性能低下。

5.2 Spectre v1/v2

攻撃者が Branch Predictor を操作 → 被害者プロセスのメモリを Cache サイドチャネルで抽出。ハードウェア設計自体の欠陥で「完全解決不能」、mitigation の積層のみ (IBRS, STIBP, retpoline)。

5.3 MDS, L1TF, ZombieLoad, Zenbleed

2019から2023年に露呈した variant 群。SMT を切るクラウドプロバイダーも登場。AWS Nitro, Google Titan, Azure Pluton はこの脅威モデル向け専用セキュリティチップ。

5.4 Post-Quantum 時代のセキュリティチップ

Apple Secure Enclave, Intel SGX/TDX, AMD SEV-SNP, ARM CCA は CPU 内部に 隔離された実行環境 を作り Kernel にも見せない。Confidential Computing のハードウェア基盤。

第6部. Apple Silicon — M1 はなぜ Intel に勝ったか

6.1 設計の勝因5つ

  1. Wide decode (10-wide vs Intel 6-wide) — x86 は可変長命令で decoder 並列化が難しいが ARM は固定32bitで容易
  2. Unified Memory Architecture (UMA) — CPU・GPU・NPU が同じ LPDDR にアクセス、コピーコスト0
  3. 巨大な ROB + 大量の Physical Register — Out-of-Order ウィンドウが Intel 比2倍
  4. SoC レベル統合 — メモリコントローラ・Thunderbolt・NVMe・Display が同一ダイでレイテンシ崩壊
  5. TSMC 5nm/3nm 先行プロセス — 同一電力で20から30%先行

6.2 P-core / E-core ハイブリッド

M シリーズは高性能コアと高効率コアを混在。バックグラウンド作業 (Spotlight インデクス、メール) は E-core に降ろしてバッテリー保護、フォアグラウンドは P-core。Windows/Linux でこのスケジューリングが複雑なのは OS がワークロード性格を推論する必要があるから (Intel の Thread Director が補助)。

6.3 Graviton/Ampere — クラウドが ARM へ移動中

AWS Graviton3/4 は同性能で 30から40%安い。Netflix・Snap・Airbnb が大規模移行。Cloudflare Workers は ARM 優先。理由は単純 — ワット当たり性能で絶対的に先行。

第7部. x86 vs ARM vs RISC-V — 2025年の地形

7.1 x86 が残る理由

だが電力効率戦で ARM に押されている。Intel は Lunar Lake (2024) からメモリをオンパッケージに載せるなど Apple 方式を模倣。

7.2 ARM が勝つ戦線

7.3 RISC-V — オープン ISA の反乱

鍵は RVA23 プロファイル標準化。Linux カーネルはすでに完全対応。

第8部. SIMD — ベクトル命令で8倍高速化

8.1 なぜ SIMD

スカラー CPU は1度に1値。SIMD は1命令で複数値を同時処理 (Single Instruction, Multiple Data)。

8.2 自動ベクトル化と手動

LLVM/GCC は単純ループを自動ベクトル化。依存や分岐混入で失敗。性能が必須なら intrinsics または std::simd (Rust portable SIMD, 2024 nightly)、std::experimental::simd (C++)。

use std::simd::f32x8;
let a = f32x8::from_array([1.0; 8]);
let b = f32x8::from_array([2.0; 8]);
let c = a + b;  // 1命令で8加算

8.3 実戦事例

第9部. GPU アーキテクチャ — CUDA Core, SM, Warp

9.1 CPU と GPU の哲学的差

GPU は Cache miss すれば他スレッドへ切替。レイテンシを 隠す。CPU は miss すれば待つだけ。

9.2 H100/B200/GB300 の内部構造

9.3 Warp Divergence — GPU の分岐コスト

同一 Warp の32スレッドが異なる分岐を取ると 両側とも実行 してマスクで棄却。つまり分岐コスト極悪。LLM カーネルが branchless で書かれる理由。

9.4 LLM inference の病目

9.5 ROCm・Apple MLX・Metal — NVIDIA 外のエコシステム

10.1 DDR5・LPDDR5X・HBM3e

10.2 NUMA の罠

2ソケットサーバーで相手側メモリアクセスは2から3倍遅い。Linux numactl, mbind で調整。Kubernetes Topology Manager がこれを認知。

2024年から現実化した標準。

意味: 「サーバー内 RAM が共有資源」になる。メモリ過剰プロビジョニングをラック単位で解消。

GPU 間直結。H100 NVLink 900 GB/s、B200 1.8 TB/s。大規模 LLM 学習の並列戦略 (TP/PP/EP) が可能になるハードウェア基盤。

第11部. 電力・熱・量子 — なぜクロックがもう上がらないか

11.1 Power Wall と Dennard Scaling の終焉

2006年頃 Dennard Scaling (Transistor が小さくなれば電力も比例減) が停止。以後クロックは3から5GHzで固着。解決策は 並列化 (コア増加) と 特化 (NPU, Tensor Core)。

11.2 Dark Silicon

200億 Transistor があっても 電力予算上同時に点けるのは一部のみ。そのため用途別専用ブロック (AMX, NPU, メディアエンジン) を埋め込んで必要時のみ点灯。

11.3 3D パッケージング

TSMC CoWoS, Intel Foveros — ロジックとメモリを垂直積層でレイテンシ/帯域爆発。B200, MI300X は3Dアセンブリ。

11.4 Quantum Computing — 2025年の現実

IBM Osprey (433 qubit), Google Willow (2024, 105 qubit + 誤り訂正ブレイクスルー), Atom Computing 1000 qubit neutral atom。「暗号破壊まではまだ遠いが最適化/化学問題で有用性を示す」段階。エンジニアへの即時影響は post-quantum crypto (Kyber, Dilithium) 準備。

第12部. 性能にどう編むか — 測定・プロファイル・チューニング

12.1 Linux perf

perf stat -d ./myapp
# instructions, cycles, IPC, cache-misses, branch-misses
perf record -g ./myapp && perf report

12.2 Intel VTune, AMD uProf, Apple Instruments

Top-Down 分析法: Retiring / Bad Speculation / Frontend Bound / Backend Bound。4つのうちどこに病目があるか1分で判断。

12.3 マイクロベンチの罠

std::chrono で100万回回して平均? コンパイラが loop-invariant と判断しコード自体を削除。black_box (Rust), benchmark::DoNotOptimize (Google Benchmark) で防止。

12.4 性能作業チェックリスト

第13部. 実戦 — 同じ言語同じアルゴリズムで10倍差が出る理由

13.1 事例1: HashMap 線形プロービング vs chaining

std::unordered_map 型 chaining は Cache miss の温床。オープンアドレッシング (linear probing) が現代 CPU で2から5倍速い。Rust の hashbrown (std HashMap ベース、Google SwissTable 移植) が代表例。

13.2 事例2: JSON パーサーが1 GB/s 可能な理由

simdjson は AVX-512/ARM NEON で一気に64バイトをスキャンし構造を把握、2回目のパスでパース。従来比10倍以上。

13.3 事例3: Redis vs KeyDB vs Dragonfly

Redis はシングルスレッド。KeyDB/Dragonfly は io_uring + shared-nothing でコア当たり線形スケール。同じハードで10から25倍スループット差。

13.4 事例4: LLM 推論 — TensorRT-LLM vs vLLM vs SGLang

第14部. ハードウェア変化がソフトウェア設計へ与える影響

14.1 NVMe + io_uring = File I/O の復活

ディスクが速くなり blocking I/O オーバーヘッドが病目化。非同期 I/O 必須。

14.2 100 Gb/s NIC + RDMA + DPDK

Network が PCIe より速くなる時代。Kernel bypass (DPDK)、RDMA (RoCEv2) 無しでは性能を出せない。Cloudflare, Meta, Stripe の edge がこの技術で動く。

14.3 DPU/IPU

NVIDIA BlueField, Intel IPU, AWS Nitro — Network/Storage/Security を CPU から分離した専用プロセッサ。2025年データセンター標準設計。

14.4 AI アクセラレータ春秋戦国

NVIDIA B200/GB300, AMD MI350X, Google TPU v5p/v6, AWS Trainium2/Inferentia3, Cerebras WSE-3, Groq LPU, Tenstorrent。各々「一分野で NVIDIA を超える」を目標。

第15部. チェックリスト12・アンチパターン10

チェックリスト12

  1. ホットパスのデータ構造が Cache フレンドリー か (配列 > linked list)
  2. Struct レイアウトが 64バイト整列・パディング を考慮したか
  3. マルチスレッド共有データに False Sharing は無いか
  4. ホットループの Branch Prediction 率 を perf で確認したか
  5. IPC 1未満 なら原因 (Cache/分岐/依存) を調査したか
  6. SIMD 機会のあるループで 自動ベクトル化が成功 したか
  7. NUMA システムなら numactl/topology manager でローカルメモリ固定したか
  8. 仮想化/クラウド vCPU の SMT ノイジーネイバー 影響を測定したか
  9. GPU ワークロードの Warp Divergence を測定したか
  10. メモリ割当を arena/slab でまとめ fragmentation を減らしたか
  11. post-quantum crypto 移行ロードマップがあるか (2030タイムライン)
  12. ARM64 ビルド (CI/CD) とベンチが準備済みか

アンチパターン10

  1. ベンチなしで「Rust は速い」信念で決定
  2. OOP AoS のみ使い SoA 未検討
  3. ホットループに HashMap 乱発
  4. アトミックカウンタ1個に全スレッド競合
  5. 仮想スレッド・async が CPU-bound 問題を解決すると考える
  6. x86 でチューニングし ARM を未テスト
  7. GPU コードで if-else により Warp Divergence を誘発
  8. memcpy 最適化に時間を使いアルゴリズムを放置
  9. KVM/VM 内部ベンチをベアメタルと同等に信頼
  10. Meltdown/Spectre mitigation を性能のため全面解除

次回予告 — 「観測可能性の現代」 — OpenTelemetry・eBPF continuous profiling・Grafana LGTM・Pyroscope・Sentry Performance・Datadog・Honeycomb・SLO・SRE・オンコール

CPU を学んだので「その CPU 上で何が起きているかリアルタイムに見る方法」が必要。次回は2025年の観測可能性を掘る。

ハードウェアからソフトウェアへ、ソフトウェアから運用へ — スタックの次層へ登る。

コメント

まだコメントはありません。

ログインするとコメントできます