2012-02-28 6 views
5

私は、malloc/free関数を大量に使うプログラミングプロジェクトを持っています。 非常に高いダイナミクスと大きい数字の3種類の構造があります。このように、mallocとfreeは頻繁に使用され、毎秒何千回も呼ばれます。 SLABのユーザスペース版による標準的なメモリ割り当ての置き換えは、この問題を解決できますか?そのようなアルゴリズムの実装はありますか?SLABのような技術を使ったCプログラムの最適化

P.S.

  1. システムはLinux向けです。
  2. 構造のサイズが100バイト未満です。
  3. 最後に、メモリ管理は本当に難しい話題なので、私は準備完了の実装を使用することをお勧めします。
+0

私のサイトをチェックしてください:https://github.com/bbu/Userland-slab-allocator :-) –

+0

@BlagovestBuyukliev:ありがとう、私自身のSLABを実装するととても役に立ちます。 いくつかのアイデアは、intresting、私はメモリ管理ではあまり強くないので、それは役に立つでしょう。 –

+0

+1はメモリ管理を認識するのが難しく、既存の実装を求めています。 –

答えて

8

プールアロケータ(カスタムメイドまたはboost::poolのようなものですが、Cの場合)を使用すると、3つだけ異なる場合は大幅に増えます。 Doug Lea's binning based mallocは、プールアロケータ(glibcで使用される)のための非常に良いベースとして機能します。

しかし、マルチスレッドやメモリの再利用(オブジェクトの割り当て、解放、再割り当て、または割り当てだけから解放されるなど)も考慮する必要があります。この角度からtcmalloc極値割り当て、量とメモリ使用量の両方)、nedmallocまたは保留を確認できます。これらのアロケータはすべてオープンソースなので、割り当てられるオブジェクトのサイズをスイートに簡単に変更することができます。

+0

質問は「C」とタグ付けされています。おそらくブーストは利用できません。 (おっと、あなたは 'boost :: pool'のように言った、申し訳ありません)。 – Kaganar

+0

@Kaganar:なぜ「好き」と言ったのか、残念ながら私は 'boost :: pool'以外の頭の上からプールアロケータを知りません。しかし、私はそれを修正します。 – Necrolis

+0

@Necrolis:ありがとう、私は自分自身の実装について考えています。私の目標に合わせて最適化されています。メモリの再利用と大粒の割り当てがあります。しかし、それは自転車の再発明のようだ。 –

1

あなたに良い答えを与えることは不可能ではありませんが、自分のメモリを管理すること(多くの場合、大きなブロックを割り当て、その大きなブロックで独自の割り当てを行うことによって)は、汎用メモリマネージャです。たとえば、Windowsでは、多くの小さな割り当てによってパフォーマンスが低下します。既存の実装はほぼすべてのタイプのメモリマネージャに存在しますが、私はどのような種類のメモリマネージャが存在するのかよく分かりません。

Windowsでプログラミングする場合、malloc /バッチ処理でメモリ割り当てを償却するアプリ内メモリ割り当ては、割り振り/解放時のプロセッサ時間を節約できます。したがって、デフォルトアロケータを呼び出していない限り、使用するアプローチはそれほど重要ではありません。

Thisは厳密スラブマネージャではありませんが、それは良いバランスを達成するようで、一般的に使用されます。

言われていること、ここでいくつかの単純なマルチスレッド・ナイーブなアイデアです。

私は個人的には、同じサイズのメモリブロックに対してかなり簡単に実装できるメモリ再利用マネージャを使用しています。固定サイズの未使用メモリのリンクリストを保持し、メモリが必要なときに。ここでのトリックは、リンクされたリストのポインタを未使用のメモリブロックに格納することです。つまり、4バイトの非常に小さなオーバーヘッドがあります。メモリーを再利用しているときは、プロセス全体がO(1)になります。

純粋に割り当て専用のスラブアロケータの場合は、システムに(大きな)チャンクを与えて追跡してもらうだけです(スムーズにスラブアロケータを呼び出すことができます)。あなたがまだ使用していないスペース(未使用領域の先頭と最後のポインタへのポインタを維持するだけです)。要求されたサイズを割り当てるのに十分なスペースがない場合は、新しいスラブを割り当てます。 (大きなチャンクの場合は、システムアロケータに渡すだけです。)

これらのアプローチを連鎖させる問題はありますか?アプリケーションはメモリーを解放しませんが、パフォーマンス重視のアプリケーションは、ワンショット処理アプリケーションであるか、同じサイズの多数のオブジェクトを作成してから使用を停止することがよくあります。

注意しておけば、上記の方法では、アトミック操作だけでもマルチスレッドを使いやすくすることは難しくありません。

1

私は最近、自分のユーザー空間スラブアロケータを実装しました。これは、大量の固定サイズ割り当てでは、malloc/freeよりもはるかに効率的(スピードワイズおよびメモリワイズ)であることが判明しました。あなたはそれを見つけることができますhere

割り振りと解放は、O(1)時間で動作し、空/フルスロットを表すためにビットベクトルが使用されているため高速化されます。割り振る際には、__builtin_ctzll GCC組み込み関数を使用して、ビットベクトル内の最初のセットビット(空のスロットを表す)を探します。これは現代のハードウェア上で単一の命令に変換する必要があります。解放するとき、対応するスラブのヘッダーを見つけ、対応するスロットを空きとしてマークするために、ポインタ自体でビット単位の賢明な計算が実行されます。

関連する問題