VMware ESXにおけるメモリ管理(11) - 仮想TLB方式ってどういうこと?

VMware ESXにおけるメモリ管理』シリーズ
(1) - 序:他のリソースとの違いはなに?
(2) - 仮想化インフラにおけるメモリ管理って?
(3) - メモリに関する仮想化支援機能(Intel EPT/VPID, AMD RVI/Tagged TLB)
(4) - メモリを割り当てるのは簡単だが、回収するのは難しい
(5) - 透過的ページ共有
(6) - Dynamic Memory on Hyper-V 実装編
(7) - Dynamic Memory on Hyper-V 設定編 +α
(8) - バルーニング
(9) - スワッピング
(10) - メモリ圧縮 (1)
…の続きです。

「メモリ圧縮(1)」と来たんだから、今回は「メモリ圧縮(2)」かと思いきや、再度脱線。今回のエントリーは下記『プロセッサを支える技術』(Hisa Ando/技術評論社)を読んでお勉強した内容の取りまとめにさせて頂きます。

プロセッサを支える技術  ??果てしなくスピードを追求する世界 (WEB+DB PRESS plus)

プロセッサを支える技術  ??果てしなくスピードを追求する世界 (WEB+DB PRESS plus)

(3) - メモリに関する仮想化支援機能(Intel EPT/VPID, AMD RVI/Tagged TLB)の内容のもうちょっと深いところといったところでしょうか。本書、とても内容が深く難しい部分も多く、正直理解し切れていない箇所も多くあるのですが、それでもとても面白い1冊でした。CPUは単なる電子計算トランジスタが超高密度に集積されただけのものだと思っていたのですが、いやいやCPUって奥深いんですね。マルチコア化することの考慮点や、なぜ1次・2次キャッシュの容量を大きくしないのか、いかに無駄なく計算サイクルを有効活用するかなど、CPUがとても「考えられて」作られているんだと思い知らされました。

さて、本書を読んでより深く理解できたのがTLB (Translation Lookaside Buffer)でした。

CPUはメモリのデータを読み書きしながら計算を行うわけですが、各プログラムが必要とするデータサイズはそれぞれ異なるため、最近のほとんどのOSはそれらのメモリ上データをページと呼ばれる単位で区切って管理する方式を採用しています。OSはどのプログラム(プロセス)のためのメモリデータがどのページに書かれているかをページテーブルを使って管理し、論理アドレスによってアクセスされたメモリデータを物理アドレスに変換しています。ページテーブルによって物理アドレスが隠匿されていることにより、プログラムから見るとフラットなメモリ空間が提供されることとなり、メモリ管理をシンプルに行うことができるようになります。

しかしページ方式におけるページテーブルにはデメリットもあります。OSがプログラム(プロセス)からの要求に対してメモリアクセスを行う場合に、毎回ページテーブルを参照していると1回のメモリアクセスのためにさらに1回の(メモリ上に保存されている)ページテーブルの参照が必要になってしまします。この問題を改善するために用意されている仕組みがTLBで、CPUはページテーブル用のキャッシュを用意することによって頻繁にアクセスされるページのインデックスを管理することにより、都度ページテーブルを参照しなくてもよいような仕組みを提供しています。

このTLBの仕組みは、仮想化においてもとても重要です。ゲストOS上のアプリケーションは論理アドレスに基づいてメモリページへのアクセスを要求するわけですが、TLBの仕組みがなければゲストOS上のアプリケーションからの要求はゲストOS側のページテーブルで「ゲストOSは物理メモリだと認識してるが実際にはHypervisor側のVMM (Virtual Machine Monitor)によって用意された仮想メモリアドレス」に変換され、さらにHypervisor/VMMは自身のページテーブルに基づいて実際の物理メモリページアドレスに変換するという2重のアドレス変換が必要となってしまいます。TLBにより、ゲストOS上から要求された論理アドレスとHypervisor/VMMによって紐づけられている物理アドレスを直接キャッシュテーブルとすることができれば、メモリアクセスに関しては「TLBにヒットする限り」は仮想化されていない場合とまったく同じ性能を発揮することができることになります。

ところが、これにてめでたしめでたしとはならないところが残念なところ。x86プロセッサではページテーブルをハードウェア的にTLBに書き込むハードウェアテーブルウォーク機構(Hardware Table Walk)を持っているため、ページテーブルとしてゲストOS上のアプリケーションが使用する論理アドレスとHypervisor/VMMが管理する物理アドレスを結びつけたページテーブル(SPT / Shadow Page Table)を用意する必要があります。また、ページテーブルはプログラム(プロセス)単位で作られるため、ゲストOS側でページテーブルが切り替えられる度にSPTを作り直すとするとオーバーヘッドが大きくなってしまいます*1

このSPTにおけるオーバーヘッド問題に対して上手くページテーブルを構成する仕組みが「仮想TLB方式」です。仮想TLB方式では、ページテーブルについてはゲストOSが自由に管理できるようにしますが、SPTはHypervisor/VMM側が管理します。ゲストOS上のアプリケーションは論理アドレスに基づいてメモリアクセスを要求しますが、最初の時点では対応する物理アドレスの情報はTLBにもSPTにも存在していないためページフォルトにより制御がHypervisor/VMMに移ります。Hypervisor/VMMはゲストOS側のページテーブルを参照し、Hypervisor/VMMが管理するページテーブルにおいて紐づけられた物理アドレスの情報をSPTに書き込みます。このような仕組みとすることで、SPTをTLBのように構成する(アクセスがあったページテーブルのエントリーを都度書き込んでいく)ことができるようになります。

仮想TLB方式ではゲストOS側のページテーブルはゲストOSが自由に変更するために仮想TLB/SPTとの間で矛盾が発生することになります。しかしこの点については、TLBのクリア処理を行う特権命令を例外とすることによって処理をHypervisor/VMMに移し、ゲストOS側のページテーブルにおける変更を仮想TLB/SPTに反映することにより問題がないように処理されます。

さて、だいぶ論理に走ってしまっていました。次回は具体的なvSphereにおける実装内容に戻りたいと思います。
上述した『プロセッサを支える技術』にはこうした解説が山のように含まれています(しかも、メモリとの話は重要な要素ではありますが、それでも主題ではない部分のほんの一部です)。このエントリーを読むような方にはとてもオススメです。

*1:VMwareが他社に先行して「実用的な」ハードウェア仮想化ソフトウェアをリリースできたのは、SPTオーバーヘッドをとても上手く管理する仕組みを作ることができたからでしょう。少なくとも、初期のハードウェア仮想化支援機能におけるVMX exit/entryよりも高速に処理できるレベルであったこっとは凄いと思います。