今回はこちらの書籍「[試して理解]Linuxのしくみ〜実験と図解で学ぶOSとハードウェアの基礎知識」 の6章 記憶階層について、自己理解のために内容をかいつまんで要約します。素晴らしい書籍で理解が進むと思いますのでぜひご購入を検討ください。
記憶階層
コンピュータにはデータを保存する場所として以下の図のようなものがあります。
メモリとディスクは皆さんご存知だと思いますがCPUにも実はデータを保存する場所があります。非常に読み書き速度は早いのですが、その分高くわずかしか書き込みができません。
ではなぜこのような速度の違う記憶階層構造になっているのでしょうか?まずお金が無限にあればすべてキャッシュメモリにすればいいはずです。それは現実的ではないので、データを貯めるのは安価なディスク(HDD/SSD)、処理を早めるためにメモリが存在しています。
キャッシュメモリはさらにCPUの性能を余すことなく使うために用意された領域でメモリへのアクセスよりも数倍〜数十倍早いです。本書には具体的にキャッシュメモリを使いメモリとCPUのデータのやり取り高速化する一連の流れが紹介されています。
階層型のキャッシュメモリ
キャッシュメモリにも実は階層があります。
今回はL1~L3と紹介しましたがCPUによってキャッシュメモリの実装が異なります。確認方法は/sys/devices/system/cpu/cpu0/cache/
の配下を見ます。
[root@master vagrant]# ls -1 /sys/devices/system/cpu/cpu0/cache/ index0 index1 index2 index3
キャッシュメモリにはそれぞれ一定のサイズが用意されており、その領域にデータを書き込むことでCPUは処理を早めています。そのためキャッシュメモリサイズを超えるデータを読み書きする場合はキャッシュメモリへのデータの出し入れが発生するため速度が遅くなります。
またキャッシュメモリによってどの論理CPUと共有するかが異なっています。以下の例ではすべてのキャッシュメモリがCPU0で使えることを表しています。
[root@master vagrant]# cat /sys/devices/system/cpu/cpu0/cache/index*/shared_cpu_list 0 0 0 0
Translation Lookaside Bufferについて
プロセスが仮想アドレスのデータにアクセスするためには
- 物理メモリ上のページテーブルを参照し、仮想アドレスを物理アドレスに変換
- 1でも止めた物理アドレスにアクセス
の流れを行う必要があります。
このときキャッシュメモリによって高速化ができるのは2だけです。というのも1はメモリ上のページテーブルにアクセスしているのでCPU→メモリの通信が発生してしまっているからです。これを解決するためにCPUにはTranslation Lookaside Buffer(TLB)と呼ばれるページテーブルを格納する領域を持っています。
ページキャッシュとバッファキャッシュ
ページキャッシュ
CPU→メモリが遅いという話をしました。しかしそれ以上にディスクへのアクセスは遅いです。これをなんとかするために使われるカーネルの仕組みがページキャッシュです。
プロセスAがファイルを読み込む処理を考えてみます。このときまずはじめにカーネルの確保しているカーネルメモリにファイルの中身がコピーされます。この領域のことをページキャシュと言います。そのあとプロセスAが持っているメモリ領域にファイルAの内容をコピーします。
なぜこんなことをしているのか?というとデータが早く読み込めるようになるからです。プロセスAが確保しているメモリ領域はプロセスAの専用です。プロセスAが作成したスレッドか自分自身であればアクセスできますが、他のプロセスはアクセスできません。しかし読み込んだファイルは複数のプロセスから参照したいこともありますよね。
カーネルメモリ上のページキャッシュは全プロセス共有の資源のため複数のプロセスがその恩恵を預かることができます。またページキャッシュを使うことでカーネルはディスクではなくメモリへのアクセスをすることで速度を向上できます。
ファイルを更新する際には先ほどの逆になります。プロセスがメモリ上のファイルを更新したらページキャッシュに反映されます。(そしてディスクよりもこのデータは新しいというフラグをつけます、このページのことをダーティーページといいます)
これにより実際はディスクに書き込まれていないものの、CPUとしては書き込みを終了したという返事をプロセスに返すことができIOの完了を待たず次の処理にすすむことができます。なおディスクへの書き込みはバックグラウンドで行われます。
バッファキャッシュ
バッファキャッシュとはファイルシステムを介さずにデバイスファイルを使ってディスクに直接アクセスするときに使う領域です。そのため利用シーンとしてはディスクをそのまま使用するDBなどで使われます。
ハイパースレッディング
プロセスがCPUを使う時間の大半はキャッシュメモリやメモリへのデータの読み書きに使われます。そのため詳細にみていくと、CPUが働いている時間は意外に少ないことがわかります。つまりもったいないということです。
これを解消するにはCPUの待ち時間を減らすために1つのCPUコアを複数にみせかけるハイパースレッディングが有効です。これによりより多くの命令が同じ時間に走るため、他の命令の待ち時間にも処理を進めることができます。ただしスループットの向上は動作するプロセスにもよるため20~30%の向上で上出来といった感じです。
まとめ
この章ではキャッシュメモリやCPUについて整理しました。書籍にはより詳しい情報や、基礎的なため今回は端折った内容も豊富に掲載されていますので勉強の際はぜひお買い求めください。