27

多くのメモリを割り当てるアプリケーションがあり、malloc よりも優れたメモリ割り当てメカニズムを使用することを検討しています。

私の主なオプションは、jemalloc と tcmalloc です。それらのいずれかを他のものよりも使用する利点はありますか?

http://locklessinc.com/benchmarks.shtmlには、いくつかのメカニズム (作成者独自のメカニズム -- ロックレスを含む) の良い比較があり 、それぞれの長所と短所について言及されています。

両方のメカニズムがアクティブであり、常に改善されていることを考えると. これら2つの相対的なパフォーマンスについて、洞察や経験を持っている人はいますか?

4

6 に答える 6

43

私の記憶が正しければ、主な違いはマルチスレッド プロジェクトでした。

どちらのライブラリも、スレッドに異なるキャッシュからメモリを選択させることでメモリ取得の競合を解消しようとしますが、戦略は異なります。

  • jemalloc(Facebook で使用) スレッドごとにキャッシュを維持します
  • tcmalloc(Google から) キャッシュのプールを維持し、スレッドはキャッシュに対して「自然な」アフィニティを開発しますが、変更される可能性があります

これも、私の記憶が正しければ、スレッド管理に関して重要な違いにつながりました。

  • jemallocプールを使用するなど、スレッドが静的な場合は高速です
  • tcmallocスレッドが作成/破棄されると高速になります

また、jemalloc新しいスレッド ID に対応するために新しいキャッシュをスピンするため、スレッドが急増すると、その後の落ち着いた段階で (ほとんどの場合) 空のキャッシュが残るという問題もあります。

その結果、tcmalloc一般的なケースで推奨し、jemalloc非常に特定の用途 (アプリケーションの存続期間中のスレッド数の変動が少ない) のために予約します。

于 2011-10-21T17:30:52.317 に答える
13

私は最近、作業中のプロジェクトでtcmallocを検討しました。これは私が観察したものです:

  • マルチスレッド設定でmallocを頻繁に使用する場合のパフォーマンスが大幅に向上しました。作業中のツールで使用したところ、パフォーマンスはほぼ2倍に向上しました。その理由は、このツールには、クリティカルループで小さなオブジェクトの割り当てを実行するスレッドがいくつかあったためです。glibcを使用すると、異なるスレッドでのmalloc / free呼び出し間のロック競合が原因で、パフォーマンスが低下すると思います。

  • 残念ながら、tcmallocはメモリフットプリントを増加させます。上記のツールは、2〜3倍のメモリを消費します(常駐セットの最大サイズで測定)。私たちは実際にメモリフットプリントを削減する方法を探しているので、フットプリントの増加は私たちにとって無駄です。

最終的に、tcmallocを使用せず、代わりにアプリケーションコードを直接最適化することにしました。これは、malloc / freeロックの競合を回避するために、内部ループから割り当てを削除することを意味します。(好奇心旺盛な方のために、メモリプールを使用するのではなく、圧縮の形式を使用してください。)

あなたにとっての教訓は、典型的なワークロードでアプリケーションを注意深く測定する必要があるということです。追加のメモリ使用量に余裕がある場合は、tcmallocが最適です。そうでない場合でも、tcmallocは、スレッド間でのメモリ割り当てへの頻繁な呼び出しを回避することで何が得られるかを確認するのに役立ちます。

于 2012-06-04T11:21:51.970 に答える
5

「nedmalloc」ホームページによると、最新の OS のアロケータは実際にはかなり高速になっていることに注意してください。

「Windows 7、Linux 3.x、FreeBSD 8、Mac OS X 10.6 にはすべて最先端のアロケーターが含まれており、サードパーティのアロケーターが実際の結果でそれらを大幅に改善する可能性は低い」

http://www.nedprod.com/programs/portable/nedmalloc

したがって、ユーザーのアップグレードなどを推奨するだけで済むかもしれません:)

于 2013-08-13T22:56:05.050 に答える
1

Boehmの保守的なガベージコレクターの使用を検討することもできます。malloc基本的に、ソースコード内のすべてをGC_malloc(etc ...)に置き換え、わざわざ.を呼び出す必要はありませんfree。BoehmのGCは、mallocよりも速くメモリを割り当てません(ほぼ同じか、30%遅くなる可能性があります)が、役に立たないメモリゾーンを自動的に処理するという利点があります。これにより、プログラムが改善される可能性があります(そして確かにコーディングが容易になります。あなたはもう無料を気にしないので)。また、ベームのGCはC++アロケータとしても使用できます。

それが本当にmalloc遅すぎると思う場合(ただし、ベンチマークを行う必要があります。ほとんどのmalloc-sはマイクロ秒未満かかります)、プログラムの割り当て動作を完全に理解している場合は、一部のmallocを特別なアロケータに置き換えることができます(これにより、たとえば、mmap自分でメモリを使用して管理し、カーネルから大きなチャンクでメモリを取得します)。しかし、それを行うのは苦痛だと思います。C ++には、アロケータの概念がありstd::allocator_traits、ほとんどの標準的なコンテナテンプレートは、そのようなアロケータを受け入れます(も参照std::allocator)。たとえば、オプションの2番目のテンプレート引数std::vectorなど。

他の人が示唆しているようにmalloc、ボトルネックであると思われる場合は、データをチャンクで(またはアリーナを使用して)、または単に配列で割り当てることができます。

場合によっては、(一部のデータに対して)専用のコピーガベージコレクターを実装すると役立つことがあります。おそらくMPSを検討してください。

ただし、時期尚早の最適化は悪であることを忘れないでください。アプリケーションのベンチマークとプロファイルを作成して、時間が失われる場所を正確に理解してください。

于 2011-10-26T21:29:02.100 に答える
1

あなたの投稿ではスレッド化について言及していませんが、C と C++ の割り当て方法を混在させることを検討する前に、メモリ プールの概念を調査します。BOOST には優れたものがあります。

于 2011-10-21T17:13:38.963 に答える
1

アロケーターについては、かなり良い議論があります:

http://www.reddit.com/r/programming/comments/7o8d9/tcmalloca_faster_malloc_than_glibcs​​_open_sourced/

于 2011-10-21T17:06:04.080 に答える