導入この論文では、HugeTLB に対応する構造体ページのメモリ使用量を最適化する革新的な方法を紹介します。 仮想化や DPDK などのシナリオでの HugeTLB の適用については、誰もがよくご存知だと思います。数百 GB のスペースを持つサーバーでは、数百 GB の HugeTLB を簡単に予約できます。多くのクラウドベンダーも、HugeTLB のメモリ管理に特定の問題があることに気づいていると思います。問題があるのに、なぜアップストリームの最適化パッチが表示されないのでしょうか? 答えは簡単です。それは難しい問題なのです。 Linux は 10 年以上にわたってメモリ管理を開発してきました。いくつかの仕組みが十分でないとしても、大きな変化を起こすのは容易ではありません。メモリ管理は Linux カーネル全体に実装されており、多くのサブシステムと相互作用します。 Linux の HugeTLB 管理の問題とは正確には何でしょうか? 物理メモリの管理方法現在、Linux カーネルは主にページ単位でメモリを管理しており、デフォルトのページ サイズは 4 KB です。物理メモリの管理を容易にするために、Linux は各ページにメタデータ構造、つまり struct page 構造を割り当てます。この構造のサイズは通常 64 バイトです。構造体ページは単純に配列として理解でき、配列のインデックスは PFN (物理ページ フレーム番号) です。この領域を vmemmap と呼びます。 イメージの 4KB ページはスモール ページと呼ばれ、その反対はラージ ページと呼ばれます。 x86-64 プラットフォームでは、ハードウェアは 2 MB および 1 GB の巨大ページをサポートします。ユーザーが大きなページを使いやすくするために、Linux は THP (Transparent Huge Page) と HugeTLB という 2 つの異なるメカニズムを提供します。 HugeTLB は私たちのエンジニアリング業務で頻繁に登場し、優れたパフォーマンスの向上をもたらします。 しかし、彼の周囲には常に暗雲が漂っている。 2 MB の HugeTLB ページには理論的には 1 つの struct ページ構造のみが必要ですが、システムの起動時に、すべての物理メモリに 4 KB 単位の struct ページ構造が割り当てられます。したがって、各 HugeTLB ページは 512 個の struct ページ構造に対応し、32 KB のメモリ (8 個の 4 KB の小さなページに相当) を占有します。 これにはどのくらいのメモリが必要か疑問に思うかもしれません。組み込みシステムの場合、これは実際には言及する価値がありません。しかし、あらゆる場所に 2 TB の物理メモリを搭載したサーバーがあることを忘れないでください。 これで簡単な計算ができるようになりました。 1 TB のサーバーで、1 TB の 2 MB の巨大ページ (理想的には) を割り当てると仮定すると、構造体ページ自体はどのくらいのメモリを占有するでしょうか?そうです、16GBです。マシンの数が数千、数万、あるいは数十万台あったらどうなるでしょうか?無駄になっている 16 GB のメモリを最適化したり、構造体ページのメモリ使用量を可能な限り削減したりできれば、サーバー プラットフォームのコストを削減できます。私たちの目標は、この暗雲を可能な限り払拭することです。 課題私たちは、他のモジュールへの影響を最小限に抑えた最もシンプルなデザインを見つけようとしましたが、その過程で多くの課題に直面しました。 1. ユーザーの適応は不要 理想的には、最適化にはユーザー モードの適応は含まれません。まったく新しいメモリ管理方法が導入された場合、すべてのユーザーがそれに適応する必要があります。私たちの目標は、すぐに使えるようにすることです。 2. 他のカーネルモジュールの機能に影響を与えない ユーザーによる調整が必要ないことが確実である限り、すべてのコード変更はカーネルに重点が置かれるものと予想されます。メモリ管理はほぼ完全に構造体ページ管理を中心に行われ、さまざまなサブシステムのモジュールはほぼすべて構造体ページと密接に関連していることがわかっています。 HugeTLB 関連の struct ページ構造をすべて強制的に解放するのは不適切です。そうしないと、カーネルのさまざまなメモリ サブシステムに影響を及ぼします。解放したいのに解放できない。これはおそらく最も困難で矛盾した問題です。 3. コードの変更を最小限に抑える コードの量は間接的にバグの数を決定します。メモリ管理サブシステムのコード変更が多すぎると、必然的にカーネルの安定性に影響します。最小限のコードで機能を実装する必要があります。これにより、バグの可能性が減るだけでなく、保守と理解も容易になります。 最初の探検写真 シンプルで直接的な方法が浮上しました。それは構造体ページの動的な割り当てと解放です。 HugeTLB の使用方法としては、使用する前に予約しておくのが一般的です。また、構造体ページはカーネル コードによってのみアクセスされるため、カーネルが構造体ページにアクセスする可能性は低いと考えられます。そこで、私たちが最初に提案した解決策は、圧縮と解凍の方法です。 HugeTLB に対応する 512 個の構造体ページに対応する情報は、約 100 バイトに圧縮できることがわかっているので、各 HugeTLB に新しいメタデータ構造を用意し、すべての情報を新しいメタデータ構造に圧縮することができます。そして、構造体ページ領域に対応するページテーブルの存在をクリアすると、対応する物理ページを解放できるようになります。それはzramメカニズムと同じですか? カーネルは、次に HugeTLB 構造体ページにアクセスするときにページ フォールトをトリガーし、フォールト内の構造体ページで必要な物理ページを割り当てて、それを解凍します (新しいメタデータ構造からデータを復元します)。 カーネルの処理が完了すると、put_page 操作が実行されます。 put_page で圧縮操作を実行し、vmemmap に対応する物理ページを解放します。アイデアは単純ですが、多くの課題が伴います。 1. ページ フォールトを割り当てることができない場合 (例: OOM) はどうすればよいですか? 2. GFP_NOWAIT を使用してメモリを割り当てると、どのコンテキストでもページ フォールトが発生する可能性がありますか?これは最初の問題をさらに悪化させるだけです。 3. A ロックを保持しているパスがページ フォールトをトリガーした場合、ページ フォールトが A ロックを保持しようとするとどうなりますか?それは行き詰まりにつながるだけです。したがって、ページ フォールト操作には特別な注意が必要です。 4. 圧縮および解凍操作をアトミックにするにはどうすればよいでしょうか?あるいは、圧縮操作と解凍操作を相互に排他的かつ同期させるにはどうすればよいのでしょうか? 5. 各 put_page 操作には圧縮が必要です。パフォーマンスへの影響はどのようなものですか? 6. 一部のカーネル パスに構造体ページにアクセスするための get 操作がない場合 (当然 put 操作もありません)、圧縮はいつ実行されますか? たくさんの問題を挙げましたが、最初の問題は解決が困難でした。このため、私たちはこのアイデアを断念せざるを得ませんでした。私たちには別の方法を見つけるしかありません。考え方を変えることで明るい未来が開けるかもしれません。 異なるアプローチ諺にもあるように、「自分と敵を知れば、百戦錬磨の人間は決して負けない」。まず、構造体ページがどのように構成され、管理されるかを詳しく理解する必要があります。あらゆる詳細を理解して初めて、計画を立てることができます。 上で述べたように、各 HugeTLB ページは 512 個の struct ページ構造に対応しており、HugeTLB は最初の 3 つの struct ページ構造のみを使用して大きなページ関連のメタデータを保存します。残りの 509 個の構造体ページは完全に無意味なのでしょうか?意味がない場合は、メモリを直接解放するだけでよいのでしょうか? しかし、物事はそれほど単純ではありません。これらの 509 個の構造体ページには、最初の構造体ページ (構造体ページの Compound_head フィールド) のアドレスが格納されます。最初の構造体ページがヘッド ページと呼ばれる場合、残りの構造体ページはテール ページと呼ばれます。 Linux カーネルのメモリ管理コードには、テール ページからヘッド ページを取得しようとするコードが多数含まれています。したがって、このメモリを単純に解放することはできません。 上図は、3 つの構造体ページの構造図を示しています (3 番目のテール ページから 511 番目の構造体ページで使用されるビット フィールドは、図の 2 番目のテール ページと同じです)。次のような特徴をまとめることができます。 1. 構造体ページ構造のサイズはほとんどの場合 64 バイトなので、各 4 KB の物理ページには整数個の構造体ページ構造を格納できます。 2. 2 番目の末尾ページから 511 番目の構造体ページまでの構造体の内容はまったく同じです。 3. メモリ管理コードでは、ヘッド ページ、第 1 テール ページ、および第 2 テール ページの構造のみが変更され、その他のテール ページ構造のメモリは変更されません。 4. 各 2MB HugeTLB ページは 512 構造体ページに対応し、メモリは 8 ページ (4KB * 8) を占有します。 5. 構造体ページが配置されている vmemmap 領域は、カーネルの線形マッピング アドレスと重複しません。 上記の特性に基づいて、新しいソリューションを提案できます。それは、HugeTLB に対応する最後の 7 ページの vmemmap 仮想アドレスを、最初の vmemmap ページに対応する物理ページ フレームにマッピングする共有マッピングです。ポイント 1 ~ 2 は共有マッピング スキームの基礎となります。ポイント 3 に基づいて、これらの 7 つの物理ページを解放し、管理のためにバディ システムに引き渡すことができます。 5 番目のポイントは、buddy がこの物理メモリを管理するための基礎です。カーネルは線形アドレスを通じて物理メモリにアクセスするため、このアドレスは vmemmap と共有できません。原理は以下の図に示されています。ポイント 3 に基づいて、異常な状況を防ぐために共有マッピング属性を読み取り専用に変更しました。 記憶のメリット上記の最適化により、サーバープラットフォームのコストを削減し、良好な利益を達成することができました。 1 GB と 2 MB の異なるサイズの HugeTLB ページでは、メモリの利点も異なります。簡単な要約表は次のとおりです。
1 GB の HugeTLB を使用すると、メモリの増加は HugeTLB 全体の約 1.6% になります。 2 MB の HugeTLB を使用すると、メモリの増加は HugeTLB の合計サイズの約 1.4% になります。 したがって、1 TB のメモリを搭載したサーバーで 1 GB の大きなページを使用すると、構造体ページのメモリ使用量の最適化がほぼ 100% 向上します。 2MB の大きなページを使用すると、構造体ページのメモリ使用量が最適化され、約 87.5% 増加します。 パフォーマンス分析vmemmap 領域マッピングの単位は 2 MB であることがわかっています。ただし、ページ テーブルを 4 KB ページ単位で変更する必要があるため、vmemmap 領域を小さなページ マッピングに変更する必要があります。これは、カーネルが vmemmap 領域にアクセスするときに、MMU が PTE ページ テーブルのもう 1 つのレベルにアクセスするのと同じです。ただし、TLB が存在するため、検索のパフォーマンスの低下は大きくありません。 しかし、vmemmap に対応する物理ページが削減されたため、パフォーマンスも向上しました。理論的には、キャッシュにヒットする可能性が高くなります。実際、これはまさにその通りです。アップストリームのテスト データによると、HugeTLB ページでの get_user_page 操作のパフォーマンスが 4 倍近く向上することが示されています。 オープンソースイニシアチブコードレビューの難易度を軽減するために、すべてのパッチを 3 つのパッチセットに分割することにしました。現在、基本機能の最初のステップは linux-next ブランチにマージされています (コード参照: [v23,0/9] HugeTLB の一部 vmemmap ページを解放、記事の左下隅をクリックすると元のテキストが読めます)。予期せぬ事態が発生しなければ、Linux 5.14 がリリースされる予定です。 次回のパッチセットも引き続きリリースする予定です。では、次にどんな機能が追加されるのでしょうか? 最初の機能は7ページを公開することです。何?これはすでに上で述べた機能ではないでしょうか?はい、しかし最初のパッチセットでは 6 ページしかリリースされませんでした。したがって、上記のパッチセットで確立したマッピング関係は、実際には次の図のようになります。これは最も単純なケースです。ヘッド ページとテール ページの構造内容は実際には異なるため、上図のマッピング関係を実装するには、いくつかのトリックが必要になります。別のパッチセットは、vmemmap ページ テーブルを分割します。最初のパッチセットの実装には、vmemmap ページ テーブルの分割は含まれませんが、代わりに、システムの起動時に、vmemmap ページ テーブルが PMD マッピングではなく PTE モードでマップされます。 著者について Song Muchun、ByteDance システム技術およびエンジニアリング チーム、Linux カーネル エンジニア。 この記事はWeChatの公開アカウント「Linux Reading Field」から転載したものです。以下のQRコードからフォローできます。この記事を転載する場合は、Linux Reading Field 公式アカウントまでご連絡ください。 |
<<: Huayun Dataの「Innovation+」エコシステムが始動:イノベーションエコシステムを強化し、革新的なパートナーを創出
この記事では、クラウド コンピューティングを使用する際に注意すべき 10 の重要なポイントをリストし...
プロモーション手法について言えば、皆さんもたくさんあると思いますので、ここでは繰り返さずに本題に入り...
仮想化データセンター向けオーバーレイネットワーク仮想拡張LAN (VXLAN)物理ネットワークの現在...
この記事を読む前に、まずは「情報フロー広告の出稿によるコンバージョン率向上の基本はマッチングである」...
ウェブマスターは皆、SEO と PPC が SEM を構成することを知っています。ほとんどのウェブマ...
[[340301]]前回の Ribbon ソース コード分析の記事で、読者から次のような質問がありま...
Sogou はこれまでずっと、非常に忠実で誠実であるという印象を人々に与えてきました。Sogou の...
Amazon Web Services (AWS) や Microsoft Azure などのパブリ...
[[436453]] [51CTO.com クイック翻訳]クラウドコンピューティングアプリケーション...
以前、私は会社で主に病院のウェブサイトの最適化を担当していました。医療ウェブサイトの最適化における競...
過去 10 年間で、多くの都市が大規模な (そして高額な)「スマート シティ」イニシアチブを立ち上げ...
A5 チャット アクティビティは、毎週木曜日の午後 2 時 30 分から 4 時まで、admin5 ...
Amazon Elastic Compute Cloud (Amazon EC2) は、クラウド内で...
weloveservers は openvz を販売していますが、大多数のネットユーザーからのフィー...
国内のモバイルインターネットは急速に発展しており、企業の具体的な実践事例を研究することは、この分野に...