C++ 内存对齐:如何使用 alignof / alignas?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17091382/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Memory alignment : how to use alignof / alignas?
提问by Offirmo
I work with shared memory right now.
我现在使用共享内存。
I can't understand alignof
and alignas
.
我无法理解alignof
和alignas
。
cppreferenceis unclear : alignof
returns "alignment" but what is "alignment" ? number of bytes to add for the next block to be aligned ? padded size ? Stack overflow/ blogs entries are unclear too.
cppreference不清楚:alignof
返回“对齐”但什么是“对齐”?要为下一个要对齐的块添加的字节数?填充尺寸 ? 堆栈溢出/博客条目也不清楚。
Can someone explain clearly alignof
and alignas
?
有人能解释清楚alignof
和alignas
?
回答by CoffeDeveloper
Alignment is a restriction on which memory positions a value's first byte can be stored. (It is needed to improve performance on processors and to permit use of certain instructions that works only on data with particular alignment, for example SSE need to be aligned to 16 bytes, while AVX to 32 bytes.)
对齐是对可以存储值的第一个字节的内存位置的限制。(需要提高处理器的性能并允许使用某些仅适用于具有特定对齐方式的数据的指令,例如 SSE 需要对齐到 16 字节,而 AVX 需要对齐到 32 字节。)
Alignment of 16 means that memory addresses that are a multiple of 16 are the only valid addresses.
16 对齐意味着只有 16 的倍数的内存地址是唯一有效的地址。
alignas
force alignment to the required number of bytes. You can only align to powers of 2: 1, 2, 4, 8, 16, 32, 64, 128, ...
强制对齐到所需的字节数。您只能对齐 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);
}
example output:
示例输出:
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
the other keyword
另一个关键字
alignof
is very convenient, you cannot do something like
很方便,你不能做类似的事情
int a[4];
assert(a % 16 == 0); // check if alignment is to 16 bytes: WRONG compiler error
but you can do
但你可以
assert(alignof(a) == 16);
assert(alignof(b) == 1024);
note that in reality this is more strict than a simple "%" (modulus) operation. In fact we know that something aligned to 1024 bytes is necessarily aligned to 1, 2, 4, 8 bytes but
请注意,实际上这比简单的“%”(模数)操作更严格。事实上,我们知道对齐 1024 字节的东西必然对齐 1、2、4、8 字节,但是
assert(alignof(b) == 32); // fail.
So to be more precise, "alignof" returns the greatest power of 2 to wich something is aligned.
因此,更准确地说,“alignof”返回 2 的最大幂以对齐某些东西。
Also alignof is a nice way to know in advance minimum alignment requirement for basic datatypes (it will probably return 1 for chars, 4 for float etc.).
此外, alignof 是一种提前了解基本数据类型的最低对齐要求的好方法(它可能会为字符返回 1,为浮点数返回 4 等)。
Still legal:
仍然合法:
alignas(alignof(float)) float SqDistance;
Something with an alignment of 16 then will be placed on the next available address that is a multiple of 16(there may be a implicit padding from last used address).
然后将对齐为 16 的内容放置在下一个可用地址上,该地址是 16 的倍数(上次使用的地址可能存在隐式填充)。
回答by Cubbi
Alignment is not padding (although padding is sometimes introduced to satisfy alignment requirements). It is an intrisic property of a C++ type. To put it in standardese (3.11[basic.align]
)
对齐不是填充(尽管有时会引入填充来满足对齐要求)。它是 C++ 类型的固有属性。把它写成标准语 ( 3.11[basic.align]
)
Object types have alignment requirements (3.9.1, 3.9.2) which place restrictions on the addresses at which an object of that type may be allocated. An alignment is an implementation-defined integer value representing the number of bytes between successive addresses at which a given object can be allocated. An object type imposes an alignment requirement on every object of that type; stricter alignment can be requested using the alignment specifier (7.6.2).
对象类型具有对齐要求(3.9.1、3.9.2),这对可以分配该类型对象的地址进行了限制。对齐是实现定义的整数值,表示可以分配给定对象的连续地址之间的字节数。对象类型对该类型的每个对象强加了对齐要求;可以使用对齐说明符 (7.6.2) 请求更严格的对齐。
回答by levengli
Each type has an alignment requirement. Generally, this is so variables of the type can be accessed efficiently, without having to cause the CPU to generate more than one read/write access in order to reach any given member of the datatype. Furthermore, it also ensure efficient copying of the entire variable. alignof
will return the alignment requirement for the given type.
每种类型都有对齐要求。通常,这样可以有效地访问该类型的变量,而不必使 CPU 生成多个读/写访问以访问该数据类型的任何给定成员。此外,它还确保有效复制整个变量。alignof
将返回给定类型的对齐要求。
alignas
is used to force an alignment on a datatype (so long as it is not less stringent that what alignof
said datatype would return)
alignas
用于强制对数据类型进行对齐(只要alignof
所述数据类型返回的内容不那么严格)