1

重複の可能性:
C++ の新しい操作によるアドレス リターンのアラインメントの保証はありますか?

このプログラムでは、unsigned chars に対してnewによって返された各アドレスを出力しています。最後にそれらを逆方向に削除します。

#include "stdafx.h"
#include<stdlib.h>
void func();

int main()
{
    int i=10;
    while(i-->0)printf("loaded %i \n", (new unsigned char));
    getchar();
    unsigned char *p=new unsigned char;printf("last pointer loaded %i \n", p);
    i=10;
    while(i-->0)delete (p-=64);
    getchar();
    p+=640;
    delete p;//nearly forgot to delete this ^^
    return 0;
}

出力:

ここに画像の説明を入力

ご覧のとおり、それぞれのnewは 64 バイトにアラインされたデータを返します。

質問:この 64 バイトは、キャッシュ ラインのサイズと同じですか、それとも単なるコンパイラの問題ですか?

質問:構造体の長さはほとんど 64 バイトにする必要がありますか?

質問: CPU、RAM、OS、またはコンパイラを変更すると、これは異なりますか?

Pentium-m、VC++ 2010 Express、windows-xp

ありがとう。

4

1 に答える 1

2

ヒープ マネージャーの実装の選択は、多数の割り当てと割り当て解除の後に何が起こるかを考えると、より理にかなっています。

への呼び出しはmalloc()、割り当てるのに十分なサイズの未使用ブロックのブロックを見つける必要があります。より大きくなる可能性があります(その場合、差のある空きブロックを作成するか、それを無駄にする可能性があります)。ブロックの最も近いサイズを見つける単純な戦略は、best fitと呼ばれます。新しい空きブロックを作成し続ける場合は、代わりに最悪の休暇と呼ぶこともできます。

使用後、ベスト フィット アプローチでは、二度と割り当てられない小さなブロックが原因で大量の断片化が発生し、空きブロックを検索するコストが高くなります。

したがって、高性能のヒープ マネージャーはこのようには機能しません。代わりに、さまざまな固定ブロック サイズのプール アロケータとして動作します。ブロックが 2 の累乗であるスキーム (例: 64,128,256,512...) は標準ですが、いくつかの中間体を投入することもおそらく価値があります (例:48,96,192...)このスキームでは、malloc()free()は両方のO(1)操作であり、割り当てのクリティカル セクションは最小限です。プールごとの可能性があります。マルチスレッド環境で重要になります。

O(n)小さな割り当てでのメモリの浪費は、断片化、割り当て/割り当て解除の複雑さ、および MT パフォーマンスの低下よりもはるかに小さな問題です。

キャッシュ ライン サイズに対する最小ブロック サイズは、これらの古典的なエンジニアリングのトレードオフの 1 つであり、Microsoft がかなりの実験を行っ64て最小値に到達したことは間違いありません。FWIW、最新の CPU のキャッシュ ラインのサイズはそれよりも大きいことがわかると思います。

于 2012-08-10T22:20:28.080 に答える