9

C ++最適化クックブックで、std :: list、std :: set、std :: multi_set、std :: map、e std::multi_mapなどのSTLコンテナーの標準アロケータをよりパフォーマンスの高いものに置き換えることができることを読みました。ブロックアロケータ

ブロックアロケータは、パフォーマンスが高く、断片化が少なく、データキャッシングが効率的です。

私はウェブ上で、標準よりも速いと主張するFSBAllocatorを見つけました。 http://warp.povusers.org/FSBAllocator/

std :: mapで試してみたところ、確かに速いようですが、私の質問は、STLの実装が特定のアロケータよりも遅くなる可能性と、標準よりも別のアロケータの欠点は何であるかということです。移植性と堅牢性の両方の?私のコードは、さまざまなアーキテクチャ(win32、osx、linux)でコンパイルする必要があります。誰かがその種の固定サイズのブロックアロケータを使った経験がありますか?

4

1 に答える 1

13

ブロック アロケーターは、フリー ストア/ヒープに 1 つの大きな割り当てを行い、その後、このメモリを内部的にチャンクに分割します。ここでの欠点の 1 つは、このチャンク (大きくする必要があり、ユース ケースごとにユーザーが指定することが多い) をまっすぐに割り当てるため、すべてを使用しなくても、そのメモリが拘束されることです。第 2 に、標準のメモリ アロケータは new / delete の上に構築され、それは多くの場合 malloc / free の上に構築されます。すべての状況で malloc / free がスレッドセーフであることが保証されているかどうかは覚えていませんが、通常は保証されています。

しかし最後に、ブロック アロケーターがうまく機能する理由は、標準のアロケーターには存在しない情報があり、非常に幅広いユース ケースをカバーする必要がないからです。たとえば、std::map< int, int >()1 MB を割り当てた場合、おそらく腹を立てますが、そうするとstd::map< int, int, std::less< int >, block_alloc< 1024 * 1024 > >()あなたはそれを期待しているでしょう。標準のアロケーターはブロックで割り当てません。それらは new を介して新しいメモリを要求しますが、new にはまったくコンテキストがありません。任意のサイズのメモリ要求を取得し、返す連続したバイト数を見つける必要があります。ほとんどの実装では、さまざまな倍数を維持するメモリ領域のセットがあるということです (たとえば、4 バイトの要求は非常に一般的であるため、4 バイトの領域が存在することが多かれ少なかれ保証されます)。リクエストが偶数倍でない場合、スペースを浪費せずに適切なチャンクを返すことが難しくなり、断片化が発生します。基本的に、任意のサイズのメモリ管理は、一定の時間に近づけたり、断片化を減らしたり、スレッドセーフにしたりする場合、非常に困難です。

ブースト プール アロケーターのドキュメントには、優れたブロック アロケーターがどのように機能するかについての良い情報があります。

于 2012-03-08T15:15:44.520 に答える