キャッシュの整理

WindowsLinuxでも何でもそうだが、プログラムを初めて立ち上げたときより2度目以降の方が高速になる。

「一回ディスクから読み込んだら、その後はディスクを介さないでメモリとアクセスするだけでよいから速いんだろう」

という以上のことを知らないので調べてみた。

キャッシュの効果

ディスクはメモリに比べて、100000〜1000000倍遅い。
ディスクアクセスを極力減らしてメモリで処理できれば、その分高速に処理できる。

ファイルキャッシュの単位

メモリ・ディスク間の読み書きはページ単位で行われる。
Linuxでは1ページは4KB。

ファイルキャッシュを利用した読み込みのフロー

1.プロセスがカーネルへデータ読み込みを要求。


2.(該当データがページキャッシュにない場合)
カーネルは新たにページキャッシュを作成し、ディスク読み込みを実行する。*1
読み込みが完了するまでプロセスはsleepする。


3.カーネルはページキャッシュからプロセスへ要求されたデータを渡す。

キャッシュを利用した書き込みのフロー

1.プロセスがカーネルへデータ書き込みを要求。


2.(該当データがページキャッシュにない場合)
カーネルは新たにページキャッシュを作成し、ページキャッシュに書き込みを実行する。
ディスクとメモリのデータが不整合になるので、Dirtyフラグを立てる。

3.その後、カーネルは他の書き込みとまとめて、ページキャッシュからディスクにデータを書き出す。Dirtyフラグを削除する。

キャッシュを使わないで読み書きして性能を測りたい、という話が以前職場であったが、これはそもそも無理だろう。

ファイルキャッシュの状況

Linuxであれば、vmstatの"cache"で使用量が調べられる。
なお、"buff"はバッファキャッシュの使用量。
バッファキャッシュとは、ファイルシステムを経由せず直接ブロックデバイスとやり取りするためのキャッシュ。

バッファキャッシュの利用例として/dev/sdaへの操作がある。

システムコール職掌範囲

上の読み込み・書き込みのフローからもわかる通り、システムコールのread(), write()は


ディスクから読み込め
ディスクへ書き込め


という命令ではない。正しくは、


ファイルキャッシュからプロセスにデータをコピーしろ
プロセスのデータをファイルキャッシュへコピーしろ


なのであった。


参考
http://www-06.ibm.com/jp/domino01/mkt/cnpages7.nsf/ec7481a5abd4ed3149256f9400478d7d/4925722f004efe92492570fc002f5e43/$FILE/Linux_IO_Subsystem_v1_2.pdf

http://www-06.ibm.com/jp/domino01/mkt/cnpages7.nsf/ec7481a5abd4ed3149256f9400478d7d/4925722f004efe92492570b2002463e2/$FILE/Linux_Memory_Management_v1_3.pdf

*1:ディスク読み込みは、プロセスが読み込み要求があったら都度行うわけではない。ディスクとのやりとりは時間がかかるので、通常ある程度要求が溜まってからカーネルの判断で実行される。