レッスン
理論 — キャッシュの局所性:読み出す順序で何が変わるか
キャッシュは、主記憶のデータのコピーを保持する、小容量で高速なメモリです。データはライン単位で保持し、各ラインにはLバイト境界にそろえたLバイトのブロックが一つ入ります。読み出すブロックがすでにラインにあればヒット、なければミスとなり、ブロック全体を読み込みます。S本のラインを持つダイレクトマップ方式のキャッシュでは、アドレスaを含むブロックの格納先は、⌊a / L⌋ mod Sで求まるライン一つに決まっています。隣り合うアドレスを順に読むループでは、一度読み込んだブロックから続けていくつも要素を読めます。この性質を空間的局所性といいます。
各記号の意味
L- ラインのバイト数。ここでは16。一般的なデスクトップやサーバーのプロセッサでは64
S- ラインの本数。ここでは8
- 前提
- 最初は空のダイレクトマップ方式のキャッシュ、4バイトのint型、Cと同じく行ごとに格納された行列を仮定します。Fortranでは列ごとに格納するため、速い読み出し順が逆になります。数えるのは行列の読み出しだけです。実際の1次データキャッシュはもっと大きく、セットアソシアティブ方式で、一般には8ウェイです。ブロックは所属するセット内の8本のラインのどこにでも置けるため、ここで見られる競合の多くは解消されますが、容量不足は解消されません。要求される前に次のラインを読み込むハードウェアプリフェッチも、このモデルには含めていません。
全プロセスの詳細解説
-
読み出し順によって、メモリからの転送量はどれだけ増えるか 4 ステップ
8 × 8を列ごとにを押し、ヒットが0回になる理由を説明してください。次に、4バイトのint型からなる1024 × 1024の行列と、ラインサイズ64バイト、容量32 KiBのダイレクトマップ方式のキャッシュを考えます。行ごとに足し合わせる場合と列ごとに足し合わせる場合、メモリから何バイト転送されるでしょうか。各行の末尾にライン1本分の余白を加えると、改善するでしょうか。
-
このページのモデルでは、1行は8 × 4 = 32バイトで、ライン2本分です。したがって行iの先頭はライン2i mod 8に割り当てられ、第0列が使うのはライン0、2、4、6だけ。a[4][0]がa[0][0]のあったラインを使うため、ループがa[0][1]に戻るときには必要なブロックがなく、64回中0回のヒットになります。行ごとなら、16バイトの各ブロックでミスは一度ずつ、計16回なので、ヒットは48回。ヒット率は1 − 4/16 = 75%です。
-
大きい方のキャッシュには、32,768 / 64 = 512本のラインがあります。行ごとに読むと、64バイトの各ラインにint型の要素が16個入り、最初の読み出しだけがミスになります。ミスは1,048,576 / 16 = 65,536回、ヒット率は1 − 4/64 = 93.75%。転送量は65,536 × 64 = 4,194,304バイトで、行列全体をちょうど一度読み込む量です。
-
列ごとでは、1行が4,096バイト、ライン64本分なので、行iの先頭はライン64i mod 512に割り当てられます。各列が使うラインは512本中8本だけです。a[8][0]がa[0][0]のブロックを追い出し、ループがa[0][1]に戻るよりずっと前に、必要なブロックは失われています。1,048,576回の読み出しがすべてミスとなり、転送量は67,108,864バイト。行ごとの16倍です。
-
各行にint型の要素16個分の余白を加えると、1行は4,160バイト、ライン65本分になります。65と512は互いに素なので、各列の割り当て先は512本すべてのラインに広がります。それでもヒットはありません。1列で読み出すブロックは1,024個、キャッシュに収まるのは512個なので、次の列で必要になる前に、どのブロックも追い出されてしまいます。
解答
行ごとは4 MiB、列ごとは64 MiB。余白によって列の割り当て先はキャッシュ全体に広がりますが、ヒットは増えません。競合は解消できても、この行列では各列で読み出すブロックだけでキャッシュ全体の容量を超えるからです。
-
学習の道すじ
コンピュータはどうやってプログラムを動かすのか
参考文献 (1)
- The first insight's measured case, the line size in the definition, and the 8-way first-level caches in `assumes`: Ulrich Drepper, "What Every Programmer Should Know About Memory," Red Hat, Inc., version 1.0, 21 November 2007. §3.2 (p. 15), §3.3.1 (pp. 17–18), §6.2.1 (pp. 49–50).