0

私は現在、アロケータの概念に基づいた c++ 用のメモリ管理ライブラリを作成しています。比較的単純です。今のところ、すべてのアロケーターが次の 2 つのメンバー関数を実装しています。

virtual void * alloc( std::size_t size ) = 0;
virtual void   dealloc( void * ptr ) = 0;

ご覧のとおり、インターフェイスでの配置はサポートしていませんが、実際にはそれが次のステップです :) そして、この質問をする理由です。

それぞれが特殊化できるため、アロケーターにアライメントの責任を負わせたいと思います。たとえば、ブロック アロケータは、ブロック サイズのアラインされたメモリのみを返すことができるため、別のアラインメントが必要な場合は、エラーを処理して NULL を返すことができます。

私のアロケーターのいくつかは、実際にはサブアロケーターです。たとえば、そのうちの 1 つは、割り当て時にポインタをバンプするだけの線形/順次アロケ​​ータです。このアロケータは、char * pBegin および char * pEnd を渡すことによって構築され、メモリ内のその領域内から割り当てます。今のところ、問題なく動作しますが、1 バイトでアラインされたものを取得します。x86 では動作しますが、他の CPU (コンソール?) では悲惨な結果になる可能性があると聞きました。また、x86 での読み取りと書き込みはやや遅くなります。

アラインされたメモリ管理を実装するために私が知っている唯一の正しい方法は、余分な sizeof( void * ) + (alignment - 1) バイトを割り当て、ポインター ビット マスキングを実行して、アラインされたアドレスを返す一方で、元の割り当てられたアドレスを前のバイトに保持することです。ユーザーデータ (void * バイト、上記参照)。

わかりました、私の質問...

割り当てごとのそのオーバーヘッドは、私には大きいようです。4 バイト アラインメントの場合、32 ビット CPU では 7 バイト、64 ビット CPU では 11 バイトのオーバーヘッドが発生します。それはたくさんのようです。

まず、多いですか?過去に使用したり、現在使用している他のメモリ管理ライブラリと同等ですか? malloc を調べたところ、最小で 16 バイトのオーバーヘッドがあるようですが、そうですか?

私のライブラリのユーザーにアライメントされたメモリを返すためのより良い方法、より小さなオーバーヘッドを知っていますか?

4

2 に答える 2

1

ポインターではなくオフセットを格納できます。これは、サポートされている最大のアライメントを格納するのに十分な大きさであるだけで済みます。小さいアラインメントのみをサポートする場合は、1 バイトで十分な場合もあります。

于 2012-12-08T20:20:34.620 に答える
0

要件に応じて、x バイト アラインできるバディ システムを実装してみてはいかがでしょうか。

一般的なアイデア:

  1. lib が初期化されたら、大きなメモリ チャンクを割り当てます。この例では、16B と仮定します。(このブロックのみを整列する必要があります。アルゴリズムでは、他のブロックを整列する必要はありません)
  2. 2 乗のメモリ チャンクのリストを維持します。つまり、4B、8B、16B、... 64KB、... 1MB、2MB、... 512MB です。
  3. ユーザーが 8B のデータを要求した場合は、8B のリストを確認します。利用できない場合は、16B のリストを確認し、8B の 2 つのブロックに分割します。1 つはユーザーに返され、もう 1 つは 8B のリストに追加されます。
  4. ユーザーが 16B を要求した場合は、少なくとも 2 つの 8B が利用可能かどうかを確認してください。はいの場合は、それらを組み合わせてユーザーに返します。そうでない場合は、システムに十分なメモリがありません。

長所:

  1. 内部または外部の断片化はありません。
  2. 位置合わせは不要です。
  3. 事前に割り当てられているメモリ チャンクへの高速アクセス。
  4. リストが配列の場合、異なるサイズのメモリ チャンクへの直接アクセス

短所:

  1. メモリのリストのオーバーヘッド。
  2. リストがリンクされたリストである場合、トラバーサルは遅くなります。
于 2012-12-08T20:45:48.227 に答える