Skip to content

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

日本語
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

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 が順次読み実行する。しかし 物理的には 大変革が起きた。

  • 1971 Intel 4004 — 4-bit、2,300 Transistor、740kHz
  • 1985 Intel 386 — 32-bit、275K Transistor、16MHz
  • 1993 Pentium — Superscalar (1サイクル2命令)、Pipeline 5段
  • 1995 Pentium Pro — Out-of-Order、Speculative Execution、Register Renaming
  • 2006 Core 2 — Intel が power wall にぶつかり「クロックではなく並列」へ
  • 2011 Sandy Bridge — 統合メモリコントローラ・AVX
  • 2020 Apple M1 — 5nm、16B Transistor、UMA、卓越した IPC
  • 2024 Intel Lunar Lake / AMD Zen 5 / Apple M4 — Performance-core + Efficiency-core ハイブリッド

一枚のチップに 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クロックで複数命令を発行する。

  • Apple M3/M4 P-core: 10-wide decode, 9-wide issue
  • Intel Golden Cove: 6-wide decode, 5-wide issue
  • AMD Zen 5: 8-wide decode, 6-wide issue

重要な理由: あなたの 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

  • ROB (Re-Order Buffer) — 実行は out-of-order、commit は in-order
  • RS (Reservation Station) — オペランドが揃えば即実行ユニットへ発射
  • Register Renaming — Architectural Register (16個) を Physical Register (数百個) にマッピング

「コード上の 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 に勝つ最大の理由」。

  • 配列 int[1000] を巡回 → 初回アクセスで16 int 一括ロード、以後15個は cache hit
  • linked list → ノードがメモリに散在、毎回 cache miss

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 まで

  • 1-bit: 直近の結果だけ記憶 → 60%精度
  • 2-bit saturating: 連続正解で確信蓄積 → 90%
  • Perceptron (AMD 2008以降): 神経網ベース → 95%以上
  • TAGE (Intel/Apple 2010年代以降): 様々な履歴長でタグ付け → 97から99%

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 が残る理由

  • レガシー互換性 (Windows/Linux/Steam ゲーム一式)
  • AVX-512, VNNI のような成熟 SIMD
  • サーバーデータセンターの慣性

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

7.2 ARM が勝つ戦線

  • モバイル (すでに100% ARM)
  • クラウド (Graviton/Ampere が30%以上)
  • Mac (100% ARM)
  • Windows on ARM (Qualcomm Snapdragon X, 2024)

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

  • 長所: ロイヤリティフリー、モジュラ拡張 (RV32I, RV64I, +M/A/F/D/V)
  • 2024から2025 シリコン: SiFive P870, Tenstorrent Ascalon, Meta MTIA, 中国 XuanTie
  • 短所: エコシステム・ソフト成熟度が不足、ベクトル拡張の断片化

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

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

8.1 なぜ SIMD

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

  • SSE (1999以降): 128-bit、float 4個
  • AVX/AVX2 (2011以降): 256-bit、float 8個
  • AVX-512 (2017以降): 512-bit、float 16個 (Intel サーバー、AMD Zen 4以降)
  • ARM NEON (2004以降): 128-bit 標準
  • SVE/SVE2 (2016以降): 可変長 (128から2048-bit)、Apple M4・Graviton3 採用
  • RISC-V V (2021以降): SVE 類似、可変長

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 実戦事例

  • simdjson: JSON パース 1から3 GB/s (スカラ比4から10倍)
  • ClickHouse: 集約クエリの SIMD 極限チューニング
  • WebP/AVIF デコード
  • LLM inference の Q4/Q8 量子化演算
  • Ripgrep の文字列検索 (memchr クレート)

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

9.1 CPU と GPU の哲学的差

  • CPU: 深い Pipeline、複雑な予測、少数スレッド、レイテンシ最小化
  • GPU: 浅い Pipeline、数万スレッド、スループット最大化

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

9.2 H100/B200/GB300 の内部構造

  • SM (Streaming Multiprocessor): GPU の「コア群」、H100 は132、B200 は208
  • CUDA Core: SM 内のスカラ ALU、SM あたり128
  • Tensor Core: 4x4 matrix multiply per cycle、LLM の中核エンジン
  • Warp: 32スレッド束が SIMT で共に実行
  • Shared Memory: SM あたり約228KB、手動管理 Cache
  • HBM3e (B200): 192GB、8TB/s

9.3 Warp Divergence — GPU の分岐コスト

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

9.4 LLM inference の病目

  • Prefill: compute-bound、Tensor Core 100%活用
  • Decode: memory-bound、KV Cache 読みが病目 → FlashAttention、PagedAttention、continuous batching
  • Blackwell B200 の FP4 (2024): メモリ帯域2倍効果

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

  • AMD ROCm は HIP で CUDA コード移植可、MI300X (HBM3 192GB) が H100 代替
  • Apple Metal + MLX: M シリーズで LLM ローカル実行、UMA でモデルロード即時
  • Intel Arc/Gaudi: OneAPI/SYCL、Gaudi3 は推論コスパ狙い

10.1 DDR5・LPDDR5X・HBM3e

  • DDR5 (デスクトップ/サーバー): 最大8400 MT/s、2ch 約90 GB/s
  • LPDDR5X (モバイル・Apple・Qualcomm): 8533 MT/s、低電力
  • HBM3e (GPU): 3D 積層、8TB/s per GPU、B200 必須

10.2 NUMA の罠

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

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

  • CXL.cache: CPU がリモートメモリを Cache 可能
  • CXL.mem: メモリプーリング・ディスアグリゲーション
  • CXL.io: PCIe 互換

意味: 「サーバー内 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
  • IPC 1未満 → miss 多い
  • branch-miss 2%超 → 予測失敗
  • LLC-load-miss 10%超 → Cache 設計失敗

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 性能作業チェックリスト

  • まず測定 → 推測禁止
  • アルゴリズム: O(n²) → O(n log n) がマイクロチューニングより常に先行
  • データレイアウト (SoA/AoS) 確認
  • 割当回数 — Rust alloc フック、jemalloc stats
  • Lock contention — perf lock, perf trace
  • SIMD 機会 — 自動ベクトル化ログ (-Rpass=loop-vectorize)

第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

  • 同一モデル、同一 GPU で処理量3から8倍差
  • 理由: KV Cache 管理、continuous batching、paged attention、CUDA graph、FP8/FP4 量子化
  • 「モデル交換」と「ランタイム交換」の効果が同等

第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年の観測可能性を掘る。

  • Metrics x Logs x Traces x Profiles — Four Pillars へ昇格
  • OpenTelemetry が事実上標準化する過程
  • eBPF continuous profiling — Parca, Pyroscope, Grafana Pyroscope, Polar Signals
  • 分散トレーシング — sampling 戦略、tail-based, head-based
  • LGTM スタック — Loki/Grafana/Tempo/Mimir
  • Sentry Performance, Datadog APM, Honeycomb 比較
  • SLO/SLI/Error Budget — SRE 本以後10年の進化
  • AI 基盤異常検知 — Datadog Watchdog, Grafana Oncall AI
  • オンコール運用 — ローテーション、ポストモーテム、ブレームレス文化

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

현재 단락 (1/193)

Rust で書いたのに C より遅いことがある。`HashMap` を使ったのに `Vec<(K,V)>` 線形探索のほうが速い瞬間がある。`if` ひとつで10倍遅くなる。なぜ M1 が同世代の I...

작성 글자: 0원문 글자: 12,269작성 단락: 0/193