キャッシュのしくみ — 速い小箱で主記憶の遅さを隠す

CPU は速い。主記憶(RAM)は遅い。その差は数十〜数百倍。そこで CPU のすぐそばに、小さくて速いキャッシュを置きます。プログラムのアクセスに潜む局所性を突いて、ほとんどのアクセスを小箱の中で済ませる。ヒットとミス、ブロック転送、マッピング方式を動かして体感します。

1. ヒットとミス — キャッシュの往復

CPU が番地を要求すると、まずキャッシュを見ます。あればヒット(数サイクルで完了)。なければミスで、遅い主記憶まで取りに行きます。このとき1語だけでなく、まわりも巻き込んだ「ブロック」単位でまとめて運び込みます。

下でアクセスパターンを選び、ステップ実行してみてください。ミスのたびに主記憶からブロックが運ばれ、同じあたりを再び使うとヒットに変わります。

CPU ⇄ キャッシュ ⇄ 主記憶
緑=ヒット(キャッシュ内で完結)、赤=ミス(主記憶へ往復)。ミス時は4語ぶんのブロックがまとめてキャッシュ行へ運ばれます。上のバーが刻々と変わるヒット率。ループやストライドで局所性のちがいを見比べてください。
POINT — ミスは高い。だからブロックで運ぶ ヒットが数サイクルなのに対し、ミスは主記憶まで数十〜数百サイクル。どうせ遠出するなら、要求された1語だけでなく隣接する数語(ブロック)をまとめて持ち帰る。「すぐ隣もどうせ使うだろう」という先読みで、次のアクセスをヒットに変える。

2. 局所性 — 時間的と空間的

キャッシュが効くのは、プログラムのアクセスが偏っているから。偏りには2種類あります。時間的局所性=「一度使った番地はすぐまた使う」(ループ変数など)。空間的局所性=「使った番地の隣もすぐ使う」(配列の連続走査など)。

下は「横=アクセスの回数、縦=番地」の地図。パターンを切り替えて、点の並び方を見てください。同じ高さに繰り返せば時間的、斜めに続けば空間的。緑がヒット、赤がミスです。

アクセスの地図 — 局所性が見える
薄い横帯が「ブロック(4語)」の区切り。順次では帯に入った最初の1回だけ赤(ミス)、続く3回は緑(ヒット)=1回のブロック転送で隣3語がタダになる空間的局所性。ループでは同じ帯を何度も叩き、温まると全部緑=時間的局所性。ランダムは赤だらけ。
POINT — 2つの局所性がキャッシュを支える 時間的局所性(同じ番地の再利用)はキャッシュに残しておく価値を生み、空間的局所性(隣接番地の利用)はブロックでまとめ運ぶ価値を生む。この2つが成り立つ限り、小さなキャッシュでも大半のアクセスを吸収できる。局所性の弱いランダムアクセスはキャッシュの天敵。

3. ダイレクトマップ vs セットアソシアティブ

運んできたブロックを、キャッシュのどの行に置くか。ダイレクトマップは「番地から計算した1つの行」に固定。単純で速い反面、同じ行に写る別ブロックが交互に来ると、容量が余っていても互いを追い出し合う競合ミスが起きます。

セットアソシアティブは1つのセットに複数の置き場(ウェイ)を用意。下は同じ容量(4行)の両方式に、競合パターンを流します。ダイレクトが総ミスで空回りする横で、2ウェイは両方を抱えられます。

同じ容量・同じアクセス — マッピング方式の勝負
左=ダイレクトマップ(4行)、右=2ウェイ・セットアソシアティブ(2セット×2行)。同じ番地列を同時に流します。「競合(2ブロック)」では、ダイレクトはヒット率がほぼ0で振動、2ウェイは温まると高ヒット率。ただし「3ブロック」では2ウェイも置き場が足りず崩れます。
注意 — 容量が余っていても起きる競合ミス ダイレクトマップの弱点は、まだ空き行があるのに同じ行を奪い合って追い出し合う点(スラッシング)。セットアソシアティブは置き場に自由度を与えて競合ミスを減らすが、ウェイ数を超える衝突には無力。連想度を上げるほど競合には強くなるが、比較回路が増え、消費電力とアクセス時間が悪化するトレードオフがある。

4. 平均アクセス時間 — 数%のヒット率が効く

キャッシュの効きめは平均アクセス時間(AMAT)で測ります。ヒットは速いがミスは高い。だからヒット率が数%変わるだけで、実効速度は大きく動きます。

AMAT — ヒット率とミスペナルティの綱引き
ヒット時間を1サイクルとしたときの、1アクセスあたりの平均コスト。ミスペナルティが大きいほど、わずかなミス率が効いてきます。ヒット率を 95% → 99% に上げるとミス率は 1/5。曲線が急に下がるのが見えます。
AMAT = ヒット時間 + ミス率 × ミスペナルティ 例:ヒット1サイクル、ミス率5%、ペナルティ100 → AMAT = 1 + 0.05×100 = 6 サイクル。ヒット率を99%に上げると 1 + 0.01×100 = 2 サイクル

5. まとめ — 局所性を現金化する装置

一歩先へ — 3種類のミスとその先 ミスは 初期参照ミス(初めて触るブロック)・容量ミス(キャッシュ全体に載りきらない)・競合ミス(同じセットの奪い合い)の3つに分けて考える。実機はこれらを、多段キャッシュ(L1/L2/L3)、書き込み方式(ライトスルー/ライトバック)、次に来そうなブロックを先読みするプリフェッチ、賢い置換ポリシーなどで削っていく。プログラムを速くする第一歩は「局所性の高いアクセスを書くこと」——データ構造とループ順序で、キャッシュは友にも敵にもなる。