Malloc バケット

malloc バケットは、デフォルトのアロケーターのオプションとしてバケット単位の拡張を提供するもので、

多数の小さな割り当て要求を出すアプリケーションの malloc パフォーマンスを改善することを目的としています。 malloc バケットが使用可能な場合、事前定義された範囲内のブロック・サイズに収まる割り当て要求は malloc バケットによって処理されます。 それ以外のすべての要求は、デフォルトのアロケーターの通常の方法で処理されます。

malloc バケットは、デフォルトでは使用できません。 これは、プロセスを始動する前に MALLOCOPTIONS 環境変数を設定することによって、使用可能にされ構成されます。

バケットの構成と見積もり

バケットは、メモリーのブロックで構成されます。 そのブロックは事前定義された数のさらに小さな同一サイズのブロックに細分化されており、 それぞれが割り当て可能なメモリーの単位です。 各バケットはバケット番号を使用して識別されます。 最初のバケットがバケット 0 で、2 番目のバケットがバケット 1 で、3 番目のバケットがバケット 2 で、以下・・・となります。 最初のバケットが最も小さく、その後の各バケットはこのセクションで後述する公式に従い、前のバケットよりも大きなサイズになります。 最大で 128 バケットを、ヒープごとに使用することができます。

各バケットのブロック・サイズは、バケット見積ファクターの倍数になります。 バケット見積ファクターは、最初のバケットのブロック・サイズと等しくなります。 2 番目のバケット内の各ブロックはこのサイズの 2 倍、3 番目のバケット内のブロックはこのサイズの 3 倍、・・・となります。 したがって、所定のバケットのブロック・サイズは、次のようにして判別されます。

ブロック・サイズ = (バケット番号 + 1) * 
バケット見積ファクター

例えば、バケット見積ファクターが 16 であれば、最初のバケット (バケット 0) のブロック・サイズは 16 バイトとなり、2 番目のバケット (バケット 1) は 32 バイト、3 番目のバケット (バケット 2) は 48 バイト、以下同様となります。

バケット見積ファクターは、malloc サブシステム関数から戻されるアドレスが必ずすべてのデータ型の場合に正しく位置合わせされるようにするために、32 ビット・インプリメンテーションの場合には 8 の倍数でなければならず、64 ビット・インプリメンテーションの場合には 16 の倍数でなければなりません。

所定のバケットのバケット・サイズは次のようにして判別されます。

バケット・サイズ = バケット当たりのブロック数 * (malloc オーバーヘッド +
              ((bucket number + 1) * bucket sizing factor))

上記の公式を使用して、それぞれのバケットが必要とする実際のバイト数を判別することができます。 この公式では、malloc オーバーヘッドはバケット内の各ブロックが必要とする内部 malloc 構成のサイズを参照します。 この内部構成は、32 ビット・アプリケーションでは 8 バイトの長さで、64 ビット・アプリケーションでは 16 バイトの長さです。 これはユーザーが使用することのできる割り当て可能スペースの一部ではありませんが、各バケットの合計サイズの一部になります。

バケット当たりのブロック数、バケット番号、およびバケット見積ファクターは、 すべて MALLOCOPTIONS 環境変数を設定することにより構成することができます。

バケットからの割り当ての処理

malloc バケットが使用可能で、割り当て要求がバケットによって定義されているブロック・サイズの範囲内に収まっているときは 必ず、バケットのいずれかから 1 つのブロックが割り当てられることになります。 それぞれの割り当て要求は、スペースを節約して使うために、選択できる最小のバケットからサービスを受けます。

あるバケットに対して割り当て要求が受信され、そのバケットのすべてのブロックが既に割り当て済みだった場合は、malloc バケットは自動的にそのバケットを拡大して、その要求をサービスできるようにします。 バケットを拡大するために追加される新しいブロックの数は、バケットに最初に入っていたブロックの数と常に等しくなります。最初に入っているブロックの数は、MALLOCOPTIONS 環境変数を設定することによって構成されます。

マルチヒープ処理のサポート

malloc マルチヒープ機能により、複数の malloc ヒープはマルチプロセッサー・システムで実行されるスレッド化されたアプリケーションのパフォーマンスを向上することができます。 malloc バケットは、ヒープごとに 128 バケットをサポートします。 これにより、malloc サブシステムは malloc バケットと malloc マルチヒープの同時使用をサポートし、 マルチプロセッサー・システムで実行されるスレッド化されたプロセスはバケット・アルゴリズムの利点を利用できます。

malloc バケットの使用可能化

malloc バケットはデフォルトでは使用可能になりませんが、 以下の環境変数を設定することによって使用可能となり構成されます。

  • MALLOCTYPE
  • MALLOCOPTIONS

Malloc バケットを使用する場合は、MALLOCTYPE 環境変数をデフォルト・アロケーターに設定する必要があります。 malloc バケットをデフォルトの設定で使用可能にするには、プロセスを始動する前に MALLOCOPTIONS=buckets を設定します。 malloc バケットをユーザー指定の構成オプションで使用可能にするには、 プロセスを始動する前に MALLOCOPTIONS=buckets,options を設定します。 ここで、options とは 1 つ以上の事前定義構成オプションをコンマで区切ってリストしたものを指します。

malloc バケットの構成オプション

MALLOCOPTIONS 環境変数を使用して、次の事前定義構成オプションのうち 1 つまたは複数を指定した malloc バケットを提供することができます。

number_of_buckets:n
bucket_sizing_factor:n
blocks_per_bucket:n
bucket_statistics:[stdout|stderr|pathname]
no_mallinfo

これらのオプションのそれぞれについては、MALLOCOPTIONS において詳細に説明します。

MALLOCOPTIONS 環境変数を使用するには、以下の構文を使用します。

MALLOCOPTIONS=[buckets,[ number_of_buckets:n | bucket_sizing_factor:n | blocks_per_bucket:n |
bucket_statistics:[stdout|stderr|pathname] | no_mallinfo],...]

コンマで区切られてさえいれば、複数のオプションを (任意の順序で) 指定することができます。 例えば、次の通りです。

MALLOCOPTIONS=buckets,number_of_buckets:128,bucket_sizing_factor:8,bucket_statistics:stderr
MALLOCOPTIONS=buckets,bucket_statistics:stdout,blocks_per_bucket:512

コンマが、この構文規則において構成オプションを区切るために有効な唯一の区切り文字です。 その他の区切り文字 (ブランクなど) をオプションとオプションの間で用いると、構成オプションが正しく構文解析されない結果となります。

各構成オプションは、MALLOCOPTIONS 環境変数の設定時に 1 回だけ指定します。 1 つの設定に対して構成オプションが複数回指定された場合は、最後のインスタンスのみが適用されることになります。

構成オプションが無効な値で指定された場合、malloc バケットは標準エラーに対して警告メッセージを書き込んでから、文書化されたデフォルト値を使用して実行を継続します。

Malloc バケットの構成オプションが malloc サブシステムによって認識されるのは、 以下の例のように buckets オプションが設定されている場合だけです。
MALLOCOPTIONS=number_of_buckets:8,buckets,bucket_statistics:stderr

Malloc バケット・オプション

number_of_buckets:n
number_of_buckets:n オプション ( n はバケットの数) を使用して、ヒープごとの使用可能なバケットの数を指定することができます。 n に指定した値が、すべての使用可能なヒープに適用されることになります。

number_of_buckets のデフォルト値は 16 です。 許される最小値は 1 で、最大値は 128 です。

bucket_sizing_factor:n
bucket_sizing_factor:n オプション (n はバイト単位で表されたバケット見積ファクター) を使用して、バケット見積ファクターを指定することができます。

bucket_sizing_factor に指定する値は、32 ビット・インプリメンテーションの場合には 8 の倍数、64 ビット・インプリメンテーションの場合には 16 の倍数でなければなりません。 bucket_sizing_factor のデフォルト値は、32 ビット・インプリメンテーションでは 32 で、64 ビット・インプリメンテーションでは 64 になります。

blocks_per_bucket:n
blocks_per_bucket:n オプション (n はブロックの数) を使用して、ブロックの数を指定することができます。 この値はすべてのバケットに対して適用されます。 また n の値は、あるバケット内のすべてのブロックが割り当て済みになってバケットが拡大されるときに、何ブロックを追加するかを決めるのにも使用されます。

blocks_per_bucket のデフォルト値は 1024 です。

bucket_statistics:[stdout|stderr|pathname]
bucket_statistics オプションを指定すると、malloc サブシステムは、malloc バケットが使用可能である間に malloc サブシステムを呼び出した各プロセスの正常終了について、malloc バケットごとの統計情報の要約を出力するようになります。 この要約では、バケット構成情報や各バケットで処理された割り当て要求の数が表示されます。 malloc マルチヒープの方法により複数のヒープが使用可能となっていた場合には、 それぞれのバケットについて示される割り当て要求は、すべてのヒープに対するそのバケットで処理された すべての割り当て要求の合計となります。

バケット統計要約は、bucket_statistics オプションでの指定に従い、以下のいずれかの出力先に書き込まれることになります。

  • stdout - 標準出力
  • stderr - 標準エラー
  • pathname - ユーザー指定のパス名

ユーザー指定のパス名が提供される場合は、統計出力は、そのファイルに何らかの既存の内容があればそれに追加されます。

あるプロセスの出力が他のプロセスへの入力としてパイピングされている場合、標準出力は、そのプロセスの出力先として 使用することはできません。

bucket_statistics オプションは、デフォルトでは使用できません。

注: 1 つの追加の割り当て要求が、統計要約を表示する atexit サブルーチンの最初のバケットに必ず表示されます。 スレッド化されたプロセスの場合は、pthreads ライブラリーによって出される malloc サブシステム呼び出しのために、いくつかのバケットに対し追加の割り当て要求が表示されます。
no_mallinfo
MALLOCOPTIONS=no_mallinfo を指定すると、mallinfo 設定が使用不可になり、malloc サブシステムで管理されるヒープの情報がログに記録されません。

malloc バケットのデフォルト構成

次の表は、malloc バケットのデフォルト構成を要約したものです。

構成オプション デフォルト値 (32 ビット) デフォルト値 (64 ビット)
ヒープ当たりのバケットの数 16 16
バケットのサイズ変更ファクター 32 バイト 64 バイト
割り当て範囲 1 から 512 バイト (を含む) 1 から 1024 バイト (を含む)
各バケットに最初に入っているブロックの数 1024 1024
バケット統計要約 使用不可 使用不可

malloc バケットのデフォルト構成は、小さな割り当て要求を数多く出す多くのアプリケーションにおいて、パフォーマンスの改良を実現するために有効であるはずですが、 MALLOCOPTIONS 環境変数を設定してデフォルト構成を変更することにより、さらに高い効果を得ることができます。 デフォルト構成を変更する前に、アプリケーションのメモリー所要量および使用方法に精通する必要があります。 その後で、バケット構成の細かな調整をする bucket_statistics オプションを指定して、malloc バケットを使用可能にします。

制限

メモリーの要件および使用方法はさまざまであるため、アプリケーションによっては、malloc バケットが使用しているメモリー割り当て方式の利点を得ることができない場合があります。 したがって、malloc バケットをシステム全体で使用可能にするのは望ましくありません。 最良のパフォーマンスを得るには、malloc バケットをアプリケーションごとに使用可能にし構成する必要があります。