第6章記憶階層
キャッシュメモリ
コンピュータシステムでは、「命令を元に、メモリからレジスタにデータを読み出す」処理と「計算結果をメモリに書き戻す」処理がボトルネックとなる。(「レジスタ上のデータを元に計算をする」処理はあまり問題にならない)
レジスタ上の計算とメモリアクセスの所要時間の差を埋めるのがキャッシュメモリ。
キャッシュメモリの動作
キャッシュメモリにデータを読み出して同じデータをレジスタに読みだす。
CPUがサイド読みだす場合、メモリへのアクセスはせずにキャッシュメモリへのアクセスだけで済む。
データの書き換えを行う場合は、変更したデータをキャッシュメモリに書き込み、キャッシュラインにダーティであることを示す印をつける。(書き込みした時点より後の所定のタイミングでバックグラウンド処理としてメモリに書き戻され、キャッシュラインはダーティではなくなるのでキャッシュラインへのアクセスのみで済む。)
キャッシュメモリがいっぱいになったらキャッシュ内に存在しないデータを読み書きすると既存のキャッシュラインの内一つを破棄して当該アドレスのデータを空けたキャッシュラインにコピーする。
階層型キャッシュメモリ
x68_64アーキテクチャのCPUはキャッシュメモリは階層型構造を取っている。
/sys/devices/system/cpu/cpu{n}/cache/index{n}/にキャッシュメモリ情報がある。
type:キャッシュするデータの種類
shared_cpu_list:キャッシュを共有する論理CPUのリスト
size:サイズ
coherency_line_size:キャッシュラインサイズ
プロセスのデータが全てキャッシュにあるうちはデータへのアクセス速度はメモリアクセスの速度ではなく、数倍速いキャッシュのアクセス速度になる。
参照の局所性
時間的局所性
ある時点でアクセスされたデータは、近い将来に再びアクセスされる可能性が高い。ループ処理の中のコード領域など。
空間的局所性
ある時点であるデータにアクセスされると、それに近いデータにアクセスする可能性が高い。配列要素の全走査など。
短期で考えれば、自身が獲得したメモリ総量よりも非常に狭い範囲のメモリにアクセスする傾向があり、この範囲がキャッシュメモリのサイズに収まっていればいい。
ページキャッシュ
ストレージデバイス上のファイルデータをメモリにキャッシュする。
ページ単位でデータを扱う。
ページキャッシュの動作
ファイルのデータを読みだす場合、カーネルのメモリ上にあるページキャッシュにコピーしてから、そのデータをプロセスのメモリにコピーする。ページキャッシュ上に存在するデータを再び読みだすと、カーネルはページキャッシュのデータを返す。
ファイルのデータに書き込む場合、カーネルはページキャッシュだけにデータを書き込み、管理領域内の当該データに相当するエントリをダーティページである印を付与する。ダーティページの内容は後から所定のタイミングでカーネルのバックグラウンド処理によってストレージ内のファイルに反映される。
各プロセスによってアクセスされるファイル上のデータが全てページキャッシュ上に存在すると、システムのファイルアクセス速度は、ストレージアクセス速度ではなく、実質的にメモリアクセス速度に近くなるため、システム全体の大幅な高速化が期待できる。
システムのメモリが足りなくなった場合
カーネルはページキャッシュを解放して空き領域を作る。
ダーティ出ないページを廃棄し、それでも足りない場合はダーティページをライトバックした後に廃棄する。後者の場合はストレージアクセスが発生するので、システムの性能が劣化する恐れがある。
バッファキャッシュ
ファイルシステムを使わずに、デバイスファイルを用いてストレージデバイスに直接アクセスする際などに使う領域。
チューニングパラメータ
ライトバック周期
sysctlのvm.dirty_writeback_centisecsで単位はセンチ秒(1/100秒)でデフォルトは5秒に1回
ライトバックを起動する全メモリのうちのダーティベージの割合
vm.dirty_background_bytesで単位は%でデフォルトは0
同期的にライトバックを行うダーティページに割合
vm.dirty_ratioで単位は%でデフォルトは20
vm.dirty_bytesだと単位はbyteでデフォルトは0
ハイパースレッド機能
CPUコアの中のレジスタなどの一部の資源を複数用意して、それぞれシステムからは論理CPUとして認識されるハイパースレッドに分割する機能。
CPU使用時間の多くはメモリあるいはキャッシュメモリからのデータ転送待ち時間に使われるため、ハイパースレッド機能で有効活用出来る。
ただしスループット性能が20〜30%程度向上すれば御の字程度。