web-dev-qa-db-ja.com

Linux上のC ++アプリケーションに「巨大な」ページを割り当てる方法

Linux上にC++アプリがあり、レイテンシーに非常に敏感です。私のメモリ使用量は約2GBなので、4kbのページと64のTLBエントリがあると、TLBミスが発生します。

Intel開発者マニュアルを読んだところ、2MB(または4MB?)の「巨大な」ページはTLBエントリの数を半分に減らすだけなので、メモリ範囲の増加はTLBエントリの減少を相殺し、パフォーマンスが向上します。

C++アプリケーションで「巨大な」ページを使用してメモリを割り当てるにはどうすればよいですか?注意すべきトレードオフはありますか?

私のLinuxはRedHatディストリビューションです。

18
user997112

C++で記述された特定のアプリケーションにのみ巨大なページが必要であると想定しています。それ以外の場合は、システムのページサイズを変更するだけです。以下の方法は、任意の言語で記述されたアプリケーションで正常に機能します。

  1. 特定のアプリケーションに巨大なページを使用するには、巨大なページのサポートをサポートするカーネルを構築する必要があります。 CONFIG_HUGETLBFSオプションを使用してカーネルを構築する必要があります

  2. 指定してページサイズを指定します

    hugepagesz=<size>
    

    ブートコマンドライン

  3. ブートパラメータの設定方法を確認するには: http://www.cyberciti.biz/tips/10-boot-time-parameters-you-should-know-about-the-linux-kernel.html

  4. 巨大なページの数を設定するには、

    # echo 20 > /proc/sys/vm/nr_hugepages
    
  5. 巨大なページをチェックするには(利用可能、合計、…)

    # cat /proc/meminfo
    
  6. 上記のすべてがうまくいったら、「特定のアプリケーションでこれらのページを使用する方法」を操作する必要があります。タイプhugetlbfsのファイルシステムをマウントします。

    # mount -t hugetlbfs -o uid=<value>,gid=<value>,mode=<value>,pagesize=<value>,size=<value>,min_size=<value>,nr_inodes=<value> none /mnt/huge
    

    アプリケーションをこのマウント/mnt/hugeブームに配置すると、アプリケーションはユーザーが設定したページサイズを使用するようになります。

詳細については、チェックしてください https://www.kernel.org/doc/Documentation/vm/hugetlbpage.txt

巨大なページの長所/短所:

メリット:TLBミスの削減、ページフォールトの削減、ページテーブルサイズの削減、翻訳の削減による効率

デメリット:内部フラグメンテーションの増加:メモリの損失、スワッピングの待ち時間の増加(HUGETLBFSページはマッピングをスワップアウトしません)詳細を確認してください https://lwn.net/Articles/359158/

[〜#〜] edit [〜#〜]巨大なページを割り当てるために利用できるAPIもありますplzチェックはおそらくそれが役立ちます

https://github.com/libhugetlbfs/libhugetlbfs/blob/master/HOWTO

https://lwn.net/Articles/375096/

7
incompetent

カーネルからの "hugetlb"ドキュメント がここで役立つはずです。

ユーザーは、mmapシステムコールまたは標準のSYSV共有メモリシステムコール(shmget、shmat)を使用して、Linuxカーネルの巨大ページサポートを使用できます。

そして:

1)map_hugetlb:tools/tests/selftests/vm /map_hugetlb.cを参照してください

2)hugepage-shm:tools/tests/selftests/vm /hugepage-shm.cを参照してください

3)hugepage-mmap:tools/tests/selftests/vm /hugepage-mmap.cを参照してください

4)libhugetlbfs( https://github.com/libhugetlbfs/libhugetlbfs )ライブラリは、巨大なページの使いやすさ、環境のセットアップ、および制御を支援するための幅広いユーザースペースツールを提供します。

(これらのパスはLinuxソースツリーを参照します)。

つまり、基本的には次のようになります。

  • mmapMAP_HUGETLBフラグとともに使用します
  • または、マウントされたhugetlbファイルシステムからファイルをマップします(存在する場合)
6
davmac

透過的な巨大ページのサポート を使用することもできます。これは、過去数年間の任意のカーネルで利用できます(少なくとも、3.xおよび4.xの範囲のすべて、およびさまざまな2.6.xカーネル) 。

主な利点は、特別な「hugetlbfs」を設定する必要がなく、「正常に機能する」ことです。欠点は、それが保証されていることです。カーネルmayは、巨大なページifが満たされ、いくつかの条件が利用可能である場合、割り当てを満たします。 。起動時に固定数の巨大なページを予約するhugetlbfsとは異なり、特定の呼び出しを介してのみ利用可能ですが、透過的な巨大なページは、一般的なメモリプールから巨大なページを切り分けます。これには、物理​​メモリの連続した2MBブロックが必要ですが、物理メモリの断片化により、時間の経過とともにまれになる可能性があります。

さらに、巨大なページを取得するかどうかに影響を与えるさまざまなカーネル調整可能ファイルがありますが、その中で最も重要なのは_/sys/kernel/mm/transparent_hugepage/enabled_です。

最善の策は、2MBの境界に_posix_memalign_でブロックを割り当ててから、割り当てられた領域でmadvise(MADV_HUGEPAGE)を実行することです。 before初めて触れる前。また、_aligned_alloc_などのバリアントでも機能します。私の経験では、_/sys/kernel/mm/transparent_hugepage/enabled_がalwaysに設定されているシステムでは、これは一般に巨大なページになります。ただし、私は主に、かなりの空きメモリがあり、稼働時間が長すぎないシステムで使用しました。

2GBのメモリを使用している場合は、巨大なページから大きなメリットを得ることができます。それをすべて小さなブロックに割り当てる場合、たとえばmallocを介して、透過的な巨大ページが起動しない可能性が高いため、メモリの大部分を使用しているもの(多くの場合、単一のオブジェクトタイプ)をTHP対応の方法で割り当てることを検討することもできます。

また、 ライブラリ を記述して、任意の割り当てから実際にhugepagesを取得したかどうかを判断します。これはおそらく実稼働アプリケーションでは役に立ちませんが、少なくともTHPを入手したかどうかを判断できるため、THPを使おうとするルートに行く場合に役立つ診断になる可能性があります。

6
BeeOnRope