align (C++)
Microsoft 固有の仕様 →
正確にはユーザー定義のデータの配置を制御するために __declspec(align(#)) を使用します (静的関数の割振または自動データ)。
__declspec( align( # ) ) declarator
解説
最近のプロセッサの命令を使用するためのアプリケーションは新しい制約および問題について説明します。特に多くの手順は新しいデータがバイト境界に配置される必要があります。また特定のプロセッサのキャッシュ ラインのサイズを頻繁に使用されるデータをマーシャリングしてキャッシュのパフォーマンスが向上します。たとえばサイズが 32 バイト未満である構造体を定義する場合その構造体の型のオブジェクトを効率的にキャッシュされるように 32 バイトに配置することもできます。
# 配置の値はです。有効なエントリは 248163264 など2 1 ~ 8192 の整数乗 (バイト単位) です。declarator は配置されるように宣言されるデータです。
型のアライメント要件である size_t 型の値を返す方法については__alignof を参照してください。と整列のポインターを宣言する方法の詳細については__unaligned ときに対象となる 64 ビット プロセッサ。
structunionまたは class を定義したり変数を宣言するとき __declspec(align(#)) を使用できます。
__declspec(align(#)) せずにVisual C++ ではデータのサイズに基づいて固有のデータはのバイト境界などバイトの整数とバイトの倍精度を配置します。クラスまたは構造体のデータは通常の配置と現在のパッキング設定の少なくともクラスまたは構造体の内部に配置されます。#pragmapack またはコンパイラ**/Zp** オプション)。
関数パラメーターの配置を指定することはできません。
次に例を示します。
__declspec(align(32)) struct Str1{
int a, b, c, d, e;
};
この型にすべてのインスタンスが 32byte の境界から開始する必要があることを意味します 32byte の配置の属性があります。要素として保存のメンバーとしてこの型に型の位置属性Str1。つまりすべての構造体宣言された追加の構造体の型に 32 以上の配置の属性があります。
まとめると、次のようになります。
__declspec(align(#)) がオーバーライドされスカラー構造体メンバーの配置サイズは現在のパッキングの最小ではありません。
__declspec(align(#)) をオーバーライドして構造体の配置はメンバーの配置の最大ではありません。
構造体メンバーの前のメンバーの終了位置のオフセット以上の配置の最小サイズの倍数となる親の構造体の先頭からのオフセットに配置されます。
構造体のサイズは配置の大きなの最小サイズの倍数でまたは最後のメンバーの終了位置のオフセットになります。
Str1 オブジェクトの配列を作成する場合は配列のベースが整列するです 32byte ようにも配列の各メンバー 32byte に配置されることに sizeof(struct Str1) 32 と同じです。基本クラスが適切に配置される配列を作成するには_aligned_malloc を使用するか独自のアロケーターを記述します。通常のアロケーターがmalloc などC++ new 演算子Win32 構造体のアロケーター declspec(align(#)) の構造体や配列に対して十分に配置されていないメモリを返すことに注意してください。
すべての構造体の sizeof の値よりどのは最終メンバーのオフセット (最も大きいメンバーの位置の値または構造体全体にの配置の値に最も近い複数の丸めがそのメンバーのサイズです。
__declspec(align(#)) は配置の制限を長くすることができます。
詳細については、次のトピックを参照してください。
例を配置します。
__declspec で新しい型を定義します (align (#))
スレッド ローカル ストレージ データの配置
データのパッキングに作業をどのように配置するか
構造体の配置例 (x64 固有)
例を配置します。
次の例では __declspec(align(#)) がデータ構造体のサイズと配置にどのように影響するかを示します。この例は次の定義を前提としています :
#define CACHE_LINE 32
#define CACHE_ALIGN __declspec(align(CACHE_LINE))
次の例ではS1 の構造は __declspec(align(32)) として定義されます。S1 のすべての使用はかまたは変数の定義またはそのほかの種類の宣言にこの構造体のデータが配置されている 32byte であることを確認します。sizeof(struct S1) は 32 を返しS1 に 4 個の整数を保持するために必要な 16 バイトに続く 16 の埋め込みのバイトがあります。int の各メンバーはの配置が必要ですが構造体の配置では32 として宣言され全体の配置は 32 です。
struct CACHE_ALIGN S1 { // cache align all instances of S1
int a, b, c, d;
};
struct S1 s1; // s1 is 32-byte cache aligned
は最大アライメント要件 (8 の倍数の倍数であることが行われるためメンバーのサイズ合計である次の例ではsizeof(struct S2) は 16 を返します。
__declspec(align(8)) struct S2 {
int a, b, c, d;
};
次の例ではsizeof(struct S3) は 64 を返します。
struct S3 {
struct S1 s1; // S3 inherits cache alignment requirement
// from S1 declaration
int a; // a is now cache aligned because of s1
// 28 bytes of trailing padding
};
次の例ではa 自然な型のアライメントこの場合4 バイトであることに注意してください。ただしS1 が整列する 32byte である必要があります。スペースの 28 バイト オフセットは 32 で a にs1 の開始されます。S4 に よっては構造体の最大アライメント要件であるためS1 の配置の要件を継承します。sizeof(struct S4) は 64 を返します。
struct S4 {
int a;
// 28 bytes padding
struct S1 s1; // S4 inherits cache alignment requirement of S1
};
次の 3 種類の変数は__declspec(align(#)) を使用します。どちらの場合も変数が配置される 32byte である必要があります。配列の場合各配列の配列メンバーではなくベース アドレスは配置された 32byte ではありません。各配列のメンバーの sizeof の値は __declspec(align(#)) の使用による影響を受けません。
CACHE_ALIGN int i;
CACHE_ALIGN int array[128];
CACHE_ALIGN struct s2 s;
配列の個々のメンバーを配置するには次のようなコードを使用する必要があります : します。
typedef CACHE_ALIGN struct { int a; } S5;
S5 array[10];
次の例では構造体を配置することに注意してください。最初に要素を配置して同じです。:
CACHE_ALIGN struct S6 {
int a;
int b;
};
struct S7 {
CACHE_ALIGN int a;
int b;
};
S6 と S7同一の配置および割り当てサイズの特性があります。
次の例ではの開始アドレスの配置bcd414および 1それぞれです。
void fn() {
int a;
char b;
long c;
char d[10]
}
メモリをヒープに割り当てられた配置はどの割り当て関数が呼び出されるかに依存します。たとえばmalloc を使用すると結果はオペランドのサイズによって決まります。 引数 >= 8 の配置が配置 8 バイトです。 引数 < 8 の配置は最初の 2 の累乗 引数 ほどの場合は。たとえばmalloc (7) を使用しての配置は 4 バイトです。
__declspec で新しい型を定義します (align (#))
配置の特性の種類を定義できます。
たとえば次のように配置の値を持つ struct を定義する :
struct aType {int a; int b;};
typedef __declspec(align(32)) struct aType bType;
次にaType と bType は同じサイズ (8 バイト) ですが bType 型の変数は配置された 32byte です。
スレッド ローカル ストレージ データの配置
__declspec(thread) の (TLS) 属性を作成して通常の静的データとまったく同じイメージ作業の TLS のセクションの配置の静的スレッド ローカル ストレージ。オペレーティング システムはデータの TLS のセクションのサイズ割り当てTLS のセクションの配置の属性を考慮してTLS でのデータを作成します。
次の例ではスレッド ローカル ストレージに配置されたデータを格納するさまざまな方法を示しています。
// put an aligned integer in TLS
__declspec(thread) __declspec(align(32)) int a;
// define an aligned structure and put a variable of the struct type
// into TLS
__declspec(thread) __declspec(align(32)) struct F1 { int a; int b; } a;
// create an aligned structure
struct CACHE_ALIGN S9 {
int a;
int b;
};
// put a variable of the structure type into TLS
__declspec(thread) struct S9 a;
データのパッキングに作業をどのように配置するか
/Zp のコンパイラ オプションおよび pack のプラグマは構造体共用体のパッキング データの処理が実行されます。/Zp と __declspec(align(#)) がどのように連携する方法を示します。:
struct S {
char a;
short b;
double c;
CACHE_ALIGN double d;
char e;
double f;
};
次の表に示す /Zp (または) pack#pragma さまざまな値に各メンバーのオフセットを対話型 2 示します。
変数 |
/Zp1 |
/Zp2 |
/Zp4 |
/Zp8 |
---|---|---|---|---|
a |
0 |
0 |
0 |
0 |
b |
1 |
2 |
2 |
2 |
c |
3 |
4 |
4 |
8 |
d |
32 |
32 |
32 |
32 |
e |
40 |
40 |
40 |
40 |
f |
41 |
42 |
44 |
48 |
_ sizeof |
64 |
64 |
64 |
64 |
詳細については、「/Zp (構造体メンバーの配置)」を参照してください。
したがってオブジェクトのオフセットは前のオブジェクトと現在のパッキング設定のオフセットに配置が前のオブジェクトのオフセットおよびオブジェクトの __declspec(align(#)) の値を基にオブジェクト __declspec(align(#)) の属性がない場合基づいています。