現在、共有メモリを使用しています。
わからないalignof
とalignas
。
cppreferenceが不明確です:alignof
「alignment」を返しますが、「alignment」とは何ですか?次のブロックを整列させるために追加するバイト数?パッド入りサイズ?スタックオーバーフロー/ブログエントリも不明確です。
誰かが明確に説明できますalignof
とalignas
?
現在、共有メモリを使用しています。
わからないalignof
とalignas
。
cppreferenceが不明確です:alignof
「alignment」を返しますが、「alignment」とは何ですか?次のブロックを整列させるために追加するバイト数?パッド入りサイズ?スタックオーバーフロー/ブログエントリも不明確です。
誰かが明確に説明できますalignof
とalignas
?
alignof
ページ上の配置の概念を説明していない理由に答えているだけでした(現在、進行中のオブジェクトページで説明しています)。cplusplus.comがどのように関連しているかわかりません。
回答:
アラインメントは、値の最初のバイトを格納できるメモリ位置の制限です。(プロセッサのパフォーマンスを向上させ、特定のアラインメントを持つデータでのみ機能する特定の命令の使用を許可する必要があります。たとえば、SSEは16バイトにアラインメントする必要があり、AVXは32バイトにアラインメントする必要があります。)
16のアラインメントは、16の倍数であるメモリアドレスが唯一の有効なアドレスであることを意味します。
alignas
必要なバイト数に強制的に調整します。2の累乗にのみ調整できます:1、2、4、8、16、32、64、128、...
#include <cstdlib>
#include <iostream>
int main() {
alignas(16) int a[4];
alignas(1024) int b[4];
printf("%p\n", a);
printf("%p", b);
}
出力例:
0xbfa493e0
0xbfa49000 // note how many more "zeros" now.
// binary equivalent
1011 1111 1010 0100 1001 0011 1110 0000
1011 1111 1010 0100 1001 0000 0000 0000 // every zero is just a extra power of 2
他のキーワード
alignof
とても便利です、あなたは次のようなことをすることはできません
int a[4];
assert(a % 16 == 0); // check if alignment is to 16 bytes: WRONG compiler error
しかし、あなたはすることができます
assert(alignof(a) == 16);
assert(alignof(b) == 1024);
実際には、これは単純な「%」(モジュラス)演算よりも厳密であることに注意してください。実際、1024バイトにアラインされたものは、必ず1、2、4、8バイトにアラインされますが、
assert(alignof(b) == 32); // fail.
つまり、より正確に言うと、「alignof」は、何かが整列されている場合に2の最大の累乗を返します。
また、alignofは、基本的なデータ型の最小アライメント要件を事前に知るための優れた方法です(charsの場合は1、floatの場合は4などを返す可能性があります)。
まだ合法:
alignas(alignof(float)) float SqDistance;
次に、16の倍数である、次に使用可能なアドレスに16の配置を持つものが配置されます(最後に使用されたアドレスからの暗黙のパディングがある場合があります)。
sizeof
、にalignof
のみ適用できtype-id
ます。
alignof()
(相手alignas()
)コンパイル時に評価され、これがない実行時のオーバーヘッド?
struct
、構造体の処理とメンバーが必要static
です。特にClangのようなコンパイラでalignas
は__attribute__((aligned))
、よりもはるかに厄介であることが判明しています。
位置合わせはパディングではありません(ただし、位置合わせの要件を満たすためにパディングが導入される場合があります)。これは、C ++タイプの本質的なプロパティです。標準化するには(3.11[basic.align]
)
オブジェクトタイプには、そのタイプのオブジェクトを割り当てることができるアドレスに制限を課す配置要件(3.9.1、3.9.2)があります。アラインメントは、特定のオブジェクトを割り当てることができる連続するアドレス間のバイト数を表す実装定義の整数値です。オブジェクトタイプは、そのタイプのすべてのオブジェクトに配置要件を課します。より厳密な配置は、配置指定子(7.6.2)を使用して要求できます。
struct X { char a; char b}
なシステムでは、サイズ2とアライメント要件1があります(charは任意のアドレスに割り当てることができるため、任意のアドレスに割り当てることができます)
alignof(std::max_align_t)
は16
、私のLinux上にある(-m32または-m64のどちらをコンパイルするかに関係なく)で最大になりますが、alignas
配置は、メモリアドレスに関連するプロパティです。簡単に言うと、アドレスXがZに位置合わせされている場合、xはZの倍数、つまりX = Zn +0です。ここで重要なのは、Zは常に2の累乗であるということです。
アラインメントはメモリアドレスのプロパティであり、2の累乗を法とする数値アドレスとして表されます。たとえば、4を法とするアドレス0x0001103Fは3です。このアドレスは4n + 3にアラインされていると言われます。ここで、4は2.アドレスのアラインメントは、選択した2の累乗に依存します。8を法とする同じアドレスは7です。アドレスのアラインメントがXn + 0の場合、アドレスはXにアラインメントされていると言われます。
上記のステートメントは、Microsoft C ++リファレンスに記載されています。
データ項目がそのサイズに合わせられたアドレスでメモリに格納されている場合、そのデータ項目は自然に位置合わせされていると言われます。そうでない場合は位置がずれています。たとえば、サイズが4バイトの整数変数が4にアラインされたアドレスに格納されている場合、変数は自然にアラインされていると言えます。つまり、変数のアドレスは4の倍数である必要があります。
コンパイラは常にミスアライメントを回避しようとします。単純なデータ型の場合、アドレスは、バイト単位の変数のサイズの倍数になるように選択されます。コンパイラーは、自然な位置合わせとアクセスのために構造体の場合にも適切にパディングします。ここで、構造体は、構造体内のさまざまなデータ項目の最大サイズに位置合わせされます。例:
struct abc
{
int a;
char b;
};
ここで、構造abcは4に整列されていますいます。これは、明らかに1バイト(charメンバーのサイズ)より大きいintメンバーのサイズです。
アラインアス
この指定子は、構造、クラスなどのユーザー定義タイプを2の累乗である特定の値に揃えるために使用されます。
alignof
これは、構造体またはクラスタイプが整列されている値を取得するための一種の演算子です。例えば:
#include <iostream>
struct alignas(16) Bar
{
int i; // 4 bytes
int n; // 4 bytes
short s; // 2 bytes
};
int main()
{
std::cout << alignof(Bar) << std::endl; // output: 16
}