操作して学ぶ

CPUキャッシュ可視化

同じ量のデータを触っても、触り方(アクセスパターン)で速度は10倍変わります。 鍵はCPUキャッシュ。メモリはラインという固まり単位でキャッシュに載るため、連続アクセスは速く、飛び飛び・ランダムは遅い。 パターンを切り替えて、ヒット率と実効レイテンシの変化を確かめてください。

メモリ(1マス=1キャッシュライン=16要素)

0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263

キャッシュ常駐 ヒット ミス

キャッシュ(0/16行・左がLRU=次に追い出される)

(空)実行するとラインが載ります

アクセス数

0

ヒット率

0.0%

ミス

0

実効レイテンシ

速い(L1 4cyc)遅い(主記憶 200cyc)

1本のラインには16要素が丸ごと載る(空間的局所性)。だから連続アクセスは最初の1回だけミスで、残り15回はヒット。 ストライドを16にすると毎回別ラインを踏むのでヒットが消える。ランダムはヒット率がほぼ「容量÷全体」に落ちる。 配列をキャッシュ容量以下(例: 16行+容量16)にすると、ランダムでも2周目から全ヒット=時間的局所性

メモリ階層と局所性

CPUに近いほど速くて小さく、遠いほど遅くて大きい。概算のアクセスコストは次の通り。数字は目安で世代により変わります。

階層概算レイテンシ容量の目安
レジスタ0サイクル数百バイト
L1キャッシュ約4サイクル数十KB
L2キャッシュ約12サイクル数百KB
L3キャッシュ約40サイクル数MB〜数十MB
主記憶(DRAM)約200サイクル数GB〜
  • 空間的局所性:近くのデータはまとめてラインで載る。だから配列を順に舐めると大半がヒットする。構造体配列(AoS)より配列構造体(SoA)が速いのもこれ。
  • 時間的局所性:一度触ったデータはしばらくキャッシュに残る。ホットなデータをキャッシュに収まる大きさに保つと速い。
  • 実務では:連結リストより配列、ランダムより連続、行優先の配列は行方向に舐める。これだけで体感が変わる。