5

私は現在、パフォーマンスが重要な組み込みアプリケーションを C で作成しています。

現在、私は次のように多くの空のメモリを割り当てています: calloc(1, num_bytes)- ただし、num_bytes以前はmalloc.

calloc-alloc ファミリでサイズに 2 つの引数を取る唯一のメモリ割り当て関数であるという点でユニークなようです。これを行う正当な理由はありますか?異なる引数を指定すると、パフォーマンスに影響がありますか? この引数のレイアウトを選択した理由は何ですか?

4

3 に答える 3

3

個別の引数を持つことの利点の1つは、整数のオーバーフローを自動的に防ぐことです。

// On a 32-bit system, the calloc will almost certainly fail, but the malloc
// will succeed to overflow, likely leading to crashes and/or security holes
// (e.g. if the number of items to allocate came from an untrusted source)
void *a = calloc(64, 67108865);  // 2^32/64 + 1
void *b = malloc(64 * 67108865);  // will allocate 64 bytes on 32-bit systems

大規模な割り当ての場合、実装はヒープの内部知識を使用して不要な作業を回避したり、キャッシュパフォーマンスを向上させたりできるため、との組み合わせのcalloc代わりに実行することでパフォーマンス上の利点が得られる場合もあります。mallocmemsetcalloc

たとえば、アロケータが、mmap(2)またはVirtualAllocより多くの仮想アドレス空間を取得するなどのOS機能を使用することを決定した場合、セキュリティ上の理由から、そのメモリは事前にゼロ調整されます。詳細な説明については、この質問を参照してください。割り当てが少ない場合、大きな違いに気付くことはほとんどありません。

一部の実装は内部でcalloc呼び出すだけなので、オーバーフローチェックの可能性以外に利点はありません。mallocmemset

于 2012-08-27T20:48:36.570 に答える
1

の引数のレイアウトは、単一のパラメータータイプのストレージ容量(64KiB程度の小さい場合もあります)calloc()よりも大きいオブジェクトサイズの割り当てを許可することであると思います。size_t

パフォーマンスが影響を受けるかどうかは、主に特定の環境で引数がどのように渡されるかに依存しcalloc()ます。通常、渡す引数が多いほど、呼び出し元と呼び出し先の間で転送されるデータが多くなります。たとえば、呼び出し先のスタックにプッシュする必要のある引数が増えると、引数をプッシュするための追加の命令がいくつか生成されます。しかし、私は信じています。この余分なオーバーヘッドは、特にメモリアロケータ自体の実行時間と比較した場合、プログラムのボトルネックにはなりません。

のパフォーマンスが心配な場合は、割り当てられたバッファを初期化しないという事実だけでcalloc()、より高速になる可能性があります。malloc()calloc()

于 2012-08-27T20:48:52.293 に答える
0

私は現在、パフォーマンスが重要なCで組み込みアプリケーションを作成しています。

calloc最適化の優先順位はかなり低くすべきだと思います。mallocただし、代わりに(ゼロ初期化を回避して)採用できるかどうかを確認しalloc、メモリを再利用し、場合によってはプラットフォーム固有の境界に埋め込まれたメモリを割り当てることで、完全に回避してください。

ただし、これらはすべて非常にマイナーな最適化です(再利用を除くalloc)。代わりに、アルゴリズムに焦点を当てます。

于 2012-08-27T20:48:25.483 に答える