web-dev-qa-db-ja.com

メモリアライメント:alignof / alignasの使用方法

現在、共有メモリを使用しています。

alignofalignasが理解できません。

cppreference は不明確です:alignofは「alignment」を返しますが、「alignment」とは何ですか?整列する次のブロックに追加するバイト数パディングサイズ? スタックオーバーフロー /ブログエントリも不明確です。

誰かがalignofalignasを明確に説明できますか?

57
Offirmo

アライメントは、値の最初のバイトを保存できるメモリ位置の制限です。 (プロセッサのパフォーマンスを改善し、特定のアライメントを持つデータでのみ動作する特定の命令の使用を許可する必要があります。たとえば、SSEは16バイトに、AVXは32バイトにアライメントする必要があります。 )

16のアライメントは、16の倍数であるメモリアドレスが唯一の有効なアドレスであることを意味します。

alignas

必要なバイト数にアラインメントを強制します(cppreferenceでは言及されていませんが、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は、基本データ型の最小アライメント要件を事前に知る良い方法です(おそらくcharに対して1、floatに対して4などを返します)。

引き続き合法:

alignas(alignof(float)) float SqDistance;

16のアライメントを持つ何かは、16の倍数である次に利用可能なアドレスに配置されます(最後に使用されたアドレスからの暗黙のパディングがあるかもしれません)。

63
GameDeveloper

アライメントはパディングではありません(ただし、アライメント要件を満たすためにパディングが導入される場合もあります)。これは、C++型の固有のプロパティです。標準(3.11[basic.align]

オブジェクトタイプには、そのタイプのオブジェクトを割り当てることができるアドレスに制限を設けるアライメント要件(3.9.1、3.9.2)があります。アラインメントは、特定のオブジェクトを割り当てることができる連続したアドレス間のバイト数を表す実装定義の整数値です。オブジェクトタイプは、そのタイプのすべてのオブジェクトに位置合わせ要件を課します。アライメント指定子(7.6.2)を使用して、より厳密なアライメントを要求できます。

7
Cubbi

各タイプにはアライメント要件があります。通常、これにより、データ型の特定のメンバーに到達するためにCPUに複数の読み取り/書き込みアクセスを生成させることなく、型の変数に効率的にアクセスできます。さらに、変数全体の効率的なコピーも保証します。 alignofは、指定されたタイプのアライメント要件を返します。

alignasは、データ型のアライメントを強制するために使用されます(データ型が返すalignofが厳密でない限り)

4
levengli