本連載はHisa Ando氏による連載「コンピュータアーキテクチャ」の初掲載(2005年9月20日掲載)から第72回(2007年3月31日掲載)までの原稿を再掲載したものとなります。第73回以降、最新のものにつきましては、コチラにて、ご確認ください。

このため、図7に示すように、プロセサはTLB(Translation Lookaside Buffer)と呼ぶ、ページテーブル専用のキャッシュを備えるのが一般的である。プログラムの仮想アドレスでのメモリアクセス要求に対して、そのアドレスがTLBに入っているかどうかをチェックし、ヒットすればその仮想アドレスに対応する実アドレスがTLBから読み出される。

  • ページテーブルによるメモリ管理

    図7 ページテーブルによるメモリ管理

図7では一番簡単なダイレクトマップ方式のTLBを示しているが、現実のマイクロプロセサでは、セットアソシアティブ方式が用いられる場合が多い。また、小規模なエントリ数の少ないTLBの場合は、CAMを使ったフルアソシアティブ方式が用いられる場合もある。

TLBタグが一致しヒットした場合は、TLBから対応する実アドレスが得られ、これを使ってメモリをアクセスすれば良い。一方、TLBをミスした場合は、メモリ上に格納されたページテーブルをアクセスして必要なエントリを読み出してTLBに格納する。このTLBミスの処理をハードウェアだけで行うプロセサもあるが、TLBミスを割り込みでOSに通知し、OSがページテーブルを読み出してTLBに書き込むという方式をとるプロセサが一般的である。

大きなメモリ領域を扱うためにはTLBのエントリ数が多い方が良いが、大きなTLBメモリは読出し速度の遅くなるという問題がある。このため、アドレス変換用にはマイクロTLBという小さなTLBを持ち、これが1次キャッシュの位置づけで、 2次キャッシュとして大容量であるが、比較的低速のメインTLBを置くという構成が一般的になってきている。但し、キャッシュラインに比べてページは単位サイズが大きいので、1次キャッシュであるマイクロTLBは16~64エントリ程度、2次キャッシュであるメインTLBは256~2Kエントリ程度のサイズが一般的である。

ページテーブルには対応する実アドレス以外に、そのページをどのような用途に使えるかを規定するフィールドがあり、読み書きが出来るRW、読出し専用のRO、そして命令として実行可能かどうかなどのページ属性を規定する。つい最近までのIA32(Intelの32ビットアーキテクチャ)プロセサでは、ページの内容を命令として実行することは不可であることを示す情報が無く、バッファオーバフローでRW属性のページに書かれたデータを命令として実行してしまい、ウィルスなどに攻撃されるウイークポイントになっていたが、最近になってこの実行を禁止する属性(NXビットとかEDビットとか呼んでいる)を追加したことは記憶に新しい。これらの情報はTLBに読み込まれて、仮想アドレスを実アドレスに変換する時に、そのアクセスが許可されたものであるかどうかのチェックが同時に行われる。

また、図7に示したページテーブルは、仮想アドレスの上位ビット全体でインデックスする1階層のものであるが、この構造ではページテーブルに必要なエントリ数が膨大になってしまう。このため、図8に示すような2階層のページテーブル構造が用いられる。Page Directory Indexと書かれた最上位のビット群で第一階層のページディレクトリのエントリを選択し、次のPage Table Indexがページテーブルのエントリを選択し、ページの実アドレスを与える。第一階層のページディレクトリの各エントリは、第二階層のページテーブルの先頭アドレスを格納しており、最大では第一階層のエントリ数だけの独立のページテーブルをサポートできるが、ページテーブルを必要としないアドレス空間に対してはエントリを無効にしておくことにより、ページテーブルに必要なメモリを削減することが出来る。特に、64bit仮想空間をサポートする場合は、2階層でも必要メモリ量が多くなりすぎるので、この概念を拡張して、3階層、4階層のページテーブルを用いるのが一般的である。

  • 2階層ページテーブル

    図8 2階層ページテーブル