どのような状況で、大きなページはスピードアップを生成できますか?

StackOverflow https://stackoverflow.com/questions/2876377

質問

最新のX86 CPUには、レガシー4K(つまり2MBまたは4MB)よりも大きなページサイズをサポートする機能があり、OS機能があります(OS機能があります。Linux, ウィンドウズ)この機能にアクセスします。

上記のMicrosoftリンクには、大きなページが「翻訳バッファーの効率が向上し、頻繁にアクセスされるメモリのパフォーマンスが向上する可能性がある」と述べています。これは、大きなページが特定の状況を改善するかどうかを予測するのにあまり役に立ちません。私は、具体的に、できれば定量化されたものに興味があります。プログラムロジック(またはアプリケーション全体)を巨大なページを使用する場所に移動すると、パフォーマンスが改善されました。誰かがサクセスストーリーを持っていますか?

私が知っている特定のケースが1つあります 私自身: :巨大なページを使用できます 劇的に 大規模なプロセスを分岐するのに必要な時間を短縮します(おそらく、コピーを必要とするTLBレコードの数が1000程度の係数によって減少するため)。エキゾチックなシナリオでも、巨大なページが利点になる可能性があるかどうかに興味があります。

役に立ちましたか?

解決 2

大きなページから可能な利益を調べるために、4KページでTLBのスラッシングを最大化するコードをいくつか作成しようとしました。以下のものが実行されます 2.6倍高速 (4kページより)2mbyteページがLibhugetlbfsのmalloc(Intel i7、64bit Debian Lenny)によって提供されている場合。うまくいけば、何が明らかです scoped_timerrandom0n 行う。

  volatile char force_result;

  const size_t mb=512;
  const size_t stride=4096;
  std::vector<char> src(mb<<20,0xff);
  std::vector<size_t> idx;
  for (size_t i=0;i<src.size();i+=stride) idx.push_back(i);
  random0n r0n(/*seed=*/23);
  std::random_shuffle(idx.begin(),idx.end(),r0n);

  {
    scoped_timer t
      ("TLB thrash random",mb/static_cast<float>(stride),"MegaAccess");
    char hash=0;
    for (size_t i=0;i<idx.size();++i) 
      hash=(hash^src[idx[i]]);
    force_result=hash;
  }

Justを使用したよりシンプルな「直線」バージョン hash=hash^src[i] 大きなページから16%しか獲得しませんでしたが、(野生の憶測)Intel's ハードウェアの派手なプリフェッチ アクセスが予測可能な場合、4Kケースを支援している可能性があります(私はできると思います プリフェッチを無効にします それが本当かどうかを調査するため)。

他のヒント

パフォーマンスの最大の違いは、メモリの大きな領域に広く間隔を置いたランダムアクセスを行っている場合に発生します。「大きい」は、TLBのすべての小さなページエントリによってマッピングできる範囲よりもはるかに大きいことを意味します(通常は通常は最新のプロセッサに複数のレベルがあります)。

物事をより複雑にするために、4KBページのTLBエントリの数は2MBページのエントリ数よりも大きいことがよくありますが、これはプロセッサによって大きく異なります。また、レベル2 TLBで利用可能な「大きなページ」エントリの数にも多くのバリエーションがあります。

たとえば、AMD Opteronファミリー10HリビジョンD( "Istanbul")システムでは、CPUIDが報告しています。

  • L1 DTLB:4KBページ:48エントリ。 2MBページ:48エントリ。 1GBページ:48エントリ
  • L2 TLB:4KBページ:512エントリ; 2MBページ:128エントリ。 1GBページ:16エントリ

Intel Xeon 56xx( "Westmere")システムで、CPUIDは次のように報告しています。

  • L1 DTLB:4KBページ:64エントリ; 2MBページ:32エントリ
  • L2 TLB:4KBページ:512エントリ; 2MBページ:なし

どちらもレベル2 TLBミスに苦しむ前に小さなページを使用して2MB(512*4KB)をマッピングできますが、Westmereシステムは32 2MB TLBエントリを使用して64MBをマッピングでき、AMDシステムはL1およびL2の176 2MB TLBエントリを使用して352MBをマッピングできます。 TLBS。どちらのシステムでも、2MBをはるかに大きく、64MB未満のメモリ範囲を介したランダムアクセスに大きなページを使用することにより、大幅なスピードアップを取得します。 AMDシステムは、はるかに大きなメモリ範囲に対して大きなページを使用して、引き続き優れたパフォーマンスを表示する必要があります。

これらすべてのケースで避けようとしているのは、X86_64階層アドレス変換の4つのレベルすべてを追跡する最悪のケース(注1)シナリオです。
住所変換キャッシュメカニズム(注2)が機能しない場合、次のことが必要です。

  • 4kbページにマッピングされたデータをロードするためのメモリへの5回の旅行、
  • 2MBページにマッピングされたデータをロードするためのメモリへの4回の旅行と
  • 1GBページにマッピングされたデータをロードするためのメモリへの3回の旅行。

いずれの場合も、メモリへの最後の旅行は要求されたデータを取得することですが、他の旅行はページ翻訳情報のさまざまな部分を取得するために必要です。私が見た最良の説明は、AMDの「AMD64アーキテクチャプログラマーズマニュアルボリューム2:システムプログラミング」のセクション5.3にあります(出版24593) http://support.amd.com/us/embedded_techdocs/24593.pdf

注1:上記の数字は実際にはありません 最悪 場合。仮想マシンの下で実行すると、これらの数字が悪化します。ページテーブルのさまざまなレベルを保持するメモリを引き起こす環境で実行してディスクに交換するとパフォーマンスが発生します 多くの 悪い。

注2:残念ながら、このレベルの詳細を知るだけでは十分ではありません。すべての最新のプロセッサには、ページ翻訳階層の上位レベルに追加のキャッシュがあるためです。私が知る限り、これらは公共の場で非常に不十分に文書化されています。

いくつかのHPC/グリッドシナリオ、特に非常に大きなモデルを備えた物理学パッケージでは、多くのRAMがある物理パッケージで改善されています。また、モデルを実行するプロセスは、マシンでアクティブな唯一のものでした。測定されていないが、特定のDB関数(バルクインポートなど)も同様に利益を得ると思われます。

個人的には、メモリアクセスプロファイルが非常によくプロファイル/理解されていて、多くの大きなメモリアクセスを実行しない限り、大幅な改善が見られる可能性は低いと思います。

これは難解になりますが、DMAメモリ転送を行うと、Intel Xeon Phi(MIC)アーキテクチャに巨大なTLBページが大きな違いをもたらします(PCIEを介してホストからPHIまで)。 このIntelリンクは、巨大なページを有効にする方法について説明します. 。通常のTLBページサイズ(4K)が8 MBを超えるDMA転送サイズが増加していることがわかりました。これは、転送サイズが512 MBに達したら、約3 GB/sから1 GB/s未満に減少しました。

巨大なTLBページ(2MB)を有効にした後、データレートは512 MBのDMA転送に対して5 GB/s以上に増加し続けました。

大きなプロセスを実行している多くのメモリ(> = 64GB)で、サーバーで〜5%のスピードアップを取得します。たとえば、16GBのJavaプロセスの場合、4m x 4kbページですが、4k x 4MBページのみです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top