3

C ++での使用シナリオがあります。このシナリオでは、何度も呼び出している関数が、いくつかのローカルで小さいが動的なサイズのベクトルを作成します。プログラムをプロファイリングした後、std :: vector :: free()に途方もない時間が費やされていることに気づきました。このような問題に対する自然な(C ++風の)解決策は、デフォルトのアロケータを私の使用シナリオにより適したものに切り替えることであるように思われました。特に、メモリプール戦略を使用することは、ここでは理にかなっているように思われました。ただし、boost::pool_allocはこれまでのところ問題に他なりません。私はそれを機能させましたが、私の小さいが頻繁に呼び出される関数(その関数をf()と呼びます)では割り当てが高速ですが、f()を呼び出す関数が非常に戻る前にハングします長い間

さらに多くのプロファイリングは、すべての時間(文字通り、待つのに飽きる前の数十分)がpool_allocator :: ordered_free()に費やされていることを示しています。単純なテストプログラムでこれと同じ動作を再現しました(極端ではありませんが)。実際、構築されたベクトルの大規模なセットがメモリをシングルトンプールに戻すと、関数は非常に長い間ハングしてから戻るようです。 。

この動作を回避する方法、またはそのような問題に悩まされていない別のC ++プールアロケータを誰かが知っているなら、私は大いに義務付けられるでしょう!

4

2 に答える 2

0

私は、すべてがうまくいくと、割り当てと解放が非常に高速になる独自のコードを数回書きました。1. サイズ別にプールのマップを作成します。2. 各プールには、二重にリンクされたブロックのリストがあります。3.各ブロックには、リストノードと所有者プールの参照、サイズチェックなどのために、前後に余分なスペースがあります。最初のエントリー。5. メモリ ブロック内にプールへのポインターがあるため、割り当て解除は高速です。6. 起動時に多数の空のプールを作成できます。次に、割り当てごとに、最初にプールからのリスト解除を試みます。それが失敗した場合は、代わりに malloc() を使用します。ブロックが解放されたら、解放する代わりにプールに戻します。7. アプリが安定して動作するようになったら、すべての割り当てはプールのリンクされたリストから直接取得され、解放はすぐそこに戻されます...超高速。8. プログラムが終了したら、プール内のすべてのメモリを Free() します。

于 2013-02-26T07:25:36.733 に答える
0

あなたの質問から、私はそれを推測します

  • 機能はこれだけ
  • ベクトルのサイズが限られている (小さいと言う)
  • 関数が再帰的にあまり頻繁に呼び出されていない

その場合は、動的に割り当てられたメモリではなく、スタック割り当てメモリを使用することを検討してください。vector を使用せずstd::array<>に、いくつかのサイズ インジケーター (格納された型が自明に構築可能である場合) または固定サイズと配置 new の生メモリ バッファーを使用するか、後者をアロケーター クラスにラップして、そのアロケーター クラスで vector を使用することにより、これを行うことができます。 .

パフォーマンスの問題がコードのこのような小さな領域に限定されている場合、boost::pool などの汎用メモリ管理ツールは使用せず、目の前の状況に非常に特化したものを使用します。

于 2013-02-26T08:53:20.210 に答える