TL

アドレス変換キャッシュの階層(TLB・PWC・ASID)

アドレス変換はなぜ遅延の支配要因にならないのか。L1/L2 TLBとページウォークキャッシュ、PCIDによるフラッシュ回避、シュートダウンのIPIコストを原理から押さえ、性能の勘所を掴めます。

応用TLBPCIDASIDページウォークキャッシュTLBシュートダウン最終更新: 2026-06-21
TL;DR要点だけ先に
  • 1.TLBはL1(小・高速)とL2(大)の階層を持ち、ミス時もページウォークキャッシュ(PWC)が上位段の物理ベースをキャッシュして実メモリ参照回数を削る。
  • 2.x86のPCIDは各TLBエントリにアドレス空間IDを付け、文脈切替でCR3を切り替えても全フラッシュを回避する。ただしKPTI併用時はカーネル/ユーザーで別IDが要る。
  • 3.他コアのTLBを揃えるシュートダウンはIPIで全該当コアに割り込むため、コア数に対してほぼ線形にコストが伸びる同期点になる。

変換キャッシュは1段ではない

MMUとTLBの内部で見たとおり、TLB は「仮想ページ番号→物理フレーム番号+属性」をキャッシュし、ヒットすればテーブルウォークを丸ごと省きます。しかし現代の CPU では、変換に関わるキャッシュは TLB 1 段ではなく、複数の階層で構成されています。なぜ階層化するのかを押さえると、ミス時のコストが「最悪 4〜5 回のメモリ参照」よりずっと小さい理由が見えてきます。

連想メモリ(CAM)は全エントリを並列照合するため、容量を増やすほど面積と遅延が増えます。そこで容量と速度を両立させるため、TLB も命令/データキャッシュと同じく階層化されます。

階層典型容量特徴
L1 ITLB / DTLB数十〜百数十エントリ命令用とデータ用に分離。1サイクル級で引ける
L2 STLB(統合)千〜数千エントリL1ミスを受ける。命令とデータを統合し容量重視
ページウォークキャッシュ数十エントリ上位段(PML4/PDPT/PD)の物理ベースを保持

L1 TLB を引いてミスすると、まず L2(STLB)を引きます。ここでヒットすればウォークは不要です。L2 でもミスして初めてページウォークが走りますが、その時も次の PWC が効きます。

ページウォークキャッシュ:ウォークの途中結果を残す

ページウォークキャッシュ(PWC。Intel では Paging-Structure Caches)は、TLB とは別物です。TLB が「最終的な変換結果(葉)」をキャッシュするのに対し、PWC はウォーク途中の上位段の物理ベースをキャッシュします。

4レベルウォーク(PWCなし): CR3 → PML4読 → PDPT読 → PD読 → PT読  = 4回の物理参照
PWCヒット(PD段までキャッシュ済):        (PML4/PDPT/PDを省略)→ PT読 = 1回

近接したアドレスは上位段(PML4・PDPT・PD のインデックス)を共有することが多く、PWC が効けば最後の数段だけ読めば済みます。同じ 2MB 領域内のページをウォークするなら、上位 3 段は同一エントリを指すため PWC ヒットが続き、実メモリ参照は最下段の 1 回に縮みます。これが「TLB ミス=常に最悪 4 回」とはならない理由です。

TLBとPWCの無効化は別管理

TLB エントリは葉の変換、PWC エントリは中間段の物理ベースを保持します。中間段のページテーブルを書き換えたのに PWC が古いベースを返すと、葉だけ無効化しても誤った下位表を読み続けます。x86 の invlpg は指定アドレスに関わる TLB と PWC の両方を無効化し、この不整合を防ぎます。

PCID:文脈切替で全フラッシュを避ける

コンテキストスイッチで CR3 を別プロセスのページテーブルに切り替えると、本来は前プロセスの TLB エントリが次プロセスに誤適用されないよう、TLB 全体をフラッシュする必要があります。x86 の PCID(Process Context Identifier) は、各 TLB エントリに 12bit のアドレス空間 ID を付与し、これを回避します。

CR4 の PCIDE ビットで機能を有効化すると、CR3 の下位 12bit が PCID フィールドとして解釈されます。TLB の照合条件は次のようになります。

ヒット条件: エントリのPCID == 現在のPCID(CR3下位12bit)
          かつ  エントリの仮想ページ番号 == 参照ページ番号

PCID が一致しないエントリはヒット扱いされないため、複数プロセスの変換が TLB に混在しても誤適用は起きません。さらに CR3 のロード時に最上位ビット(bit 63)を立てると、「この PCID の既存エントリをフラッシュしない」ことを CPU に指示でき、戻ってきたプロセスの残存エントリをそのまま再利用できます。これが切替コストを下げる核心です。

PCIDは12bitしかない

PCID は 4096 個(0〜4095)しかありません。実プロセス数がこれを超えると ID を使い回す必要があり、OS は ID を再割り当てする際に該当 PCID のエントリを明示的に無効化します。Linux は全プロセスに固定 ID を配らず、各 CPU ごとに少数(既定で 6 個)の PCID をプロセスへ動的に貸与する LRU 的な管理で、限られた ID を効率配分しています。

KPTIとPCIDの相互作用

投機実行のOS対策で導入された KPTI(カーネルページテーブル分離)は、ユーザー空間用とカーネル空間用にページテーブルを 2 つ持ち、システムコールや割り込みのたびに CR3 を切り替えます。これは PCID と密接に絡みます。

KPTI 下では同一プロセスでも「ユーザー用」「カーネル用」で別の PCID を割り当てます。もし同じ PCID を使うと、ユーザー/カーネル切替のたびにそのエントリをフラッシュせざるを得ず、PCID の利点が消えるためです。ID を分ければ、両方のエントリが TLB に共存し、頻繁な CR3 切替でもフラッシュが不要になります。PCID を持たない CPU で KPTI を有効にすると、システムコール往復ごとに TLB フラッシュが発生し、オーバーヘッドが顕著に重くなります。

TLBシュートダウン:他コアを揃えるIPIコスト

マルチコアでは各コアが独立した TLB を持ちます。あるコアがページテーブルを書き換えて自分の TLB を無効化しても、他コアの TLB には古い変換が残ります。これを揃える処理が TLB シュートダウンで、munmapmprotect、ページ移行などマッピングを変える操作で必要になります。

x86 にはハードウェアでの遠隔 TLB 無効化命令が(広くは)ないため、OS がソフトウェアで全該当コアに依頼します。手順はおおむねこうです。

1. 開始コア: 自分のTLBを invlpg で無効化
2. 対象コアの集合を決定(そのアドレス空間を実行中のCPU)
3. 各対象コアへ IPI(プロセッサ間割り込み)を送出
4. 各対象コア: 割り込みハンドラ内で該当エントリを無効化
5. 開始コア: 全対象コアの完了応答を待ってから処理を続行

ここで効くのが 割り込みコントローラ(APIC)です。IPI は APIC を介して送られ、受信側はハンドラ実行のため実行中の処理を中断します。コストの本質は次の 3 点です。

コスト要因内容
IPI送出と割り込み処理対象コア数に比例。各コアでハンドラ実行と本来処理の中断が発生
完了待ち(同期点)最も遅いコアの応答まで開始コアがブロックする
キャッシュ・パイプライン擾乱割り込みで対象コアのキャッシュ局所性が乱れる二次コスト

対象コア数が増えるほどコストはほぼ線形に伸び、完了待ちは最も遅いコアに律速されます。これが、多コア環境で頻繁な munmap やページ移行が性能の落とし穴になる原理です。Linux はこれを緩和するため、対象を「実際にそのアドレス空間を実行している CPU」だけに絞り、mm_cpumask で無関係なコアへの IPI を省きます。

遅延フラッシュの落とし穴

コストを嫌って無効化を遅らせると、解放済み物理ページを古い権限で参照し続ける窓が開きます。Linux はバッチ化(複数の無効化をまとめて 1 回のシュートダウンにする)で IPI 回数を減らしますが、バッチが確定するまでページを解放しないことで安全性を担保します。性能のための遅延と安全性の境界は、この「解放を待つ」点にあります。

試験のポイント

「TLB は L1/L2 の階層を持ち、PWC は上位段の物理ベースを別にキャッシュする」「PCID/ASID は各エントリに空間 ID を付け、切替時の全フラッシュを回避する」「TLB シュートダウンは IPI で他コアに無効化を依頼し、コア数に対してほぼ線形にコストが伸びる」の3点が頻出です。PWC は最終変換ではなく中間段をキャッシュする点、PCID は命令ではなく CR3 と連動するハードウェア機構である点に注意。

まとめ

  • TLB は L1(小・高速)と L2(大) の階層を持ち、L1 ミスでも L2 ヒットならウォークを省ける。
  • ページウォークキャッシュ(PWC) は上位段の物理ベースを保持し、ミス時の実メモリ参照を削るため「ミス=常に最悪段数」にはならない。
  • PCID/ASID は各エントリに空間 ID を付け、CR3 切替でも全フラッシュを回避する。KPTI 併用時はユーザー/カーネルで別 ID が必要。
  • TLB シュートダウンは IPI で他コアの TLB を揃える同期点で、対象コア数にほぼ線形でコストが伸びる。

前提となる変換機構はMMUとTLBの内部、表構造の詳細は多段ページテーブルの構造も合わせてどうぞ。

OS Article

アドレス変換キャッシュの階層(TLB・PWC・ASID)を実務で読む

TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。

解決すること

TLB

比較で見る軸

難易度: advanced / カテゴリ: OS / タグ数: 5

導入後に効く点

x86のPCIDは各TLBエントリにアドレス空間IDを付け、文脈切替でCR3を切り替えても全フラッシュを回避する。ただしKPTI併用時はカーネル/ユーザーで別IDが要る。

先に潰すリスク

用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。

数字・仕様の読み方
難易度
advanced
カテゴリ
OS
タグ数
5

判断チェックリスト

  • 自社の用途が「TLB / PCID」に近いか確認する。
  • 強みである「TLBはL1(小・高速)とL2(大)の階層を持ち、ミス時もページウォークキャッシュ(PWC)が上位段の物理ベースをキャッシュして実メモリ参照回数を削る。」が本当に評価軸になるか確認する。
  • 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
  • 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
  • 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
  • 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。

次に確認する観点

TLBPCIDASIDページウォークキャッシュTLBシュートダウンTLBPCIDASID
参考: 公式情報