[Linux] hugetlbfs: Not just for databases anymore!

原文はこちら。
https://blogs.oracle.com/linuxkernel/hugetlbfs%3a-not-just-for-databases-anymore

仮想メモリを実装するオペレーティングシステムは、仮想アドレスから物理アドレスへの変換を行う必要があります。このような変換はソフトウェアによって完全に達成できますが、現代のプロセッサメモリ管理ユニット(MMU)はこのプロセスを高速化するメカニズムを提供しています。これは、Translation Lookaside Buffer(TLB)と呼ばれるもので、最近使用された仮想メモリから物理メモリへの変換をキャッシュに保持することで実現します。TLBのサイズは限られているため、TLB内に変換がない場合はパフォーマンスが低下します。Huge Pageを使用するとTLBミスを回避できます。同じ量のデータを含めるのに必要なページ数を少なくすることで、限られた数のTLBエントリで競合が少なくなります。
Linuxは、2002年にv2.5.36カーネルでhuge pageをサポートしました。この初期のサポートはhugetlbfsと呼ばれ、すべてがファイルである従来のUnixモデルに従っていました。hugetlbfsを使用するには、明示的にhugetlbfsファイルシステムをマウントする必要がありました。さらに重要なのは、huge pageの可用性を保証するために、起動時または直後に事前に割り当てる必要がありました。さらに、アプリケーションプログラムは、hugetlbfsのhuge pageを使用するように変更する必要がありました。これらのすべての要求事項ゆえに、hugetlbfsは平均的なアプリケーションでは使用されません。 hugetlbfsがニッチな場所を見つけたのは、大量のメモリに対処し、可能な限り最高のパフォーマンスを望むデータベースです。データベースは、hugetlbfsを活用する最初のタイプのアプリケーションの1つであり、現在でも大きなユースケースとして残っています。

hugetlbfsで必要な構成とアプリケーションの変更の問題に対処するために、Transparent Huge Pages (THP)と呼ばれる新たなhuge pageモデルが開発されました。この名前が示すように、通常THPでは、huge pageを利用するための設定やアプリケーションの変更を必要としません。アプリケーション内のマッピングでhuge pageを利用出来る場合、カーネルはそれらのマッピングにhuge pageを使用しようとします。この機能は、ほとんどのLinuxディストリビューションではデフォルトで有効になっており、可能であれば、プログラムはhuge pageを透過的に使用します。


今日、Linuxでのhuge page開発の大半はTHPが中心です。最近のTHPへの追加には、ext4ファイルシステムへのサポートを追加しようとしているページキャッシュのサポートが含まれます。このアイデアは、より多くのマッピングをTHPと互換性を持たせて、huge pageの使用が透過的に広がるようにするというものです。Linuxではhuge pageといえばTHPではありますが、まだhugetlbfsに対していくつかの変更が加えられています。少ないながらもいくつかの重要なアプリケーションでは、引き続きhugetlbfsに依存しています。対象とするこれらのアプリケーションとシステムでは、hugetlbfsが提供する制御と予測可能性を考慮すると、構成とアプリケーションの変更の要件は受け入れ可能です。データベースに加えて、仮想化、高頻度取引(High Frequency Trading)の分野や、さらにはJavaアプリケーションでは、今日もなおhugetlbfsを採用しています。以下は、これらのユースケースで採用されている、あまり知られていないhugetlbfsの機能の一部です。
  • 複数のhuge pageサイズhugetlbfsを使うと、ハードウェアとカーネルでサポートされているすべてのhuge pageサイズを使用できます。x86システムでは、1GBのhuge pageとデフォルトの2MBのサイズを使用できます。PowerPCのようなアーキテクチャの場合、512KB、1MB、2MB、8MB、16MB、1GB、および16GBといった、ずっと多くのhuge pageサイズを備えています。メモリ使用量とアクセスパターンを明示的に認識しているアプリケーションでは、最適なhuge pageサイズを選択できます。最近のカーネルでは、ほとんどのアーキテクチャがデフォルトですべてのhuge pageサイズを有効にしています。mmap(2)システムコールでは、hugetlbfsマッピングの背景とするためにhuge pageサイズを指定できます。
  • huge pagesの動的割り当て
    ほとんどのhugetlbfsのユーザーは、アプリケーションが必要とするhuge pageが、アプリケーションが必要なタイミングで利用できる保証が必要です。このため、通常はhuge pageがブート時に事前に割り当てられます。事前割り当ては、huge pageが利用可能であることの保証に備えていますが、事前割り当てしたhuge pageの場所を保証するものではありません。事前割り当て時に、メモリポリシーを介してhuge pageの位置を指定できます。しかし、事前割り当て時よりもはるかに後に実行されているアプリケーションがhuge pageの場所を判定するのは困難です。結果として、いくつかのhugetlbfs使用モデルでは、mmap(2)またはページフォルト時のhuge page動的割り当てを利用してきました。これにより、アプリケーションはhuge pageの配置をより詳細に制御できます。ただし、huge pageの動的に割り当てるを保証するものではありません。したがって、アプリケーションはmmap(2)呼び出し時の障害に対処するか、未解決ページフォルトが原因で発生するSIGBUSを受け取る準備が必要です。
  • fallocateのサポート
    これはデータベースからの要求で追加されました。事前割り当て機能は、huge pageを予約する単純なmmap(2)呼び出しでhugetlbfsファイルをあらかじめ割り当てることができるので、それほどエキサイティングではありません。興味深い機能はhole punchです。以前ファイルに割り当てられたhuge pageを削除できます。huge pageは一般的に希少なものなので、この機能を使って、インテリジェントなアプリケーションが不要になったページを解放して他の目的に使用できます。
  • userfaultfdのサポート
    userfaultfdの最初の使用例は、fallocateのhole punchで作成されたホールへのアクセスを捕まえることでした。インテリジェントなアプリケーションが再度使用しないためにページをリリースした場合、それはエラーを示すため、後続のアクセスをキャッチしたかったのです。しかし、サポートが追加された後、hugetlbfsのuserfaultfdはQEMUのpost copyライブマイグレーションで使用できることが判明しました。ベースページサイズのページは、以前はライブマイグレーションに使用されていましたが、十分なネットワーク帯域幅では、より大きいhugetlbfsページを使用するとマイグレーションを高速化できます。
  • memfd_createとファイルシーリング
    Oracle Javaは新しいガベージ・コレクション・スキームを策定しました。このスキームを容易にするために、メモリヒープのために複数のマッピングが必要でした。ヒープは匿名メモリとして割り当てられます。Linuxでは、memfd_create(2)システムコールを使用して、匿名メモリを使用するtmpfsファイルを作成できます。この匿名メモリへの複数のマッピングを作成するために、memfd_create(2)が返すファイルディスクリプタを利用でき、この新しいスキームでうまく機能します。ただし、JVMには現在、ヒープを戻すためにhuge pageを使用することもできます。この状況を助けるために、hugetlbfsサポートがmemfd_create(2)に追加されました。これにより、huge pageを背景とする匿名メモリの複数のマッピングを作成できます。この機能が追加された直後に、別のユースケースが浮上しました。hugetlbfsのmemfd_create(2)は、QEMUがDPDK vHostユーザーのサポートに使用できます。
Linuxは現在THPに重点を置いているため、今日重要なアプリケーションでhugetlbfsが使用されていることが忘れられてしまいがちですが、新しい機能が追加されると、新しいユースケースが浮上します。hugetlbfsは、15年以上前に導入されたときと同じく有用であり、これはデータベースだけで使われるものではありません。

0 件のコメント:

コメントを投稿