内存alignment:如何使用alignof / alignas?
我现在使用共享内存。
我无法理解alignof
和alignas
。
cppreference不清楚: alignof
返回“alignment”,但什么是“alignment”? 要为下一个要alignment的块添加的字节数? 填充大小? 堆栈溢出 /博客条目也不清楚。
有人可以清楚地alignof
和alignas
?
alignment是限制哪个内存位置可以存储一个值的第一个字节。 (需要提高处理器的性能,并允许使用某些只适用于具有特定alignment数据的指令,例如SSE需要alignment到16个字节,而AVXalignment到32个字节。)
16的alignment意味着是16的倍数的存储器地址是唯一有效的地址。
alignas
强制alignment到所需的字节数(cppreference没有提到它,但我认为你只能alignment2: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);
请注意,实际上这比简单的“%”(模数)操作更严格。 实际上,我们知道,alignment到1024字节的东西必然与1,2,4,8字节alignment
assert(alignof(b) == 32); // fail.
所以更准确地说,“alignof”返回最大的2的权力,以使得某些东西alignment。
另外,alignof是事先知道基本数据types的最小alignment要求的一个好方法(它可能返回1为字符,4为浮点数等)。
依然合法:
alignas(alignof(float)) float SqDistance;
那么,alignment为16的东西将被放置在下一个可用地址的16倍 (可能是上一次使用的地址的隐式填充)。
alignment不是填充(尽pipe填充有时会引入以满足alignment要求)。 这是一个C ++types的内在属性。 把它放在标准( 3.11[basic.align]
)
对象types具有alignment要求(3.9.1,3.9.2),该对要求限制了可以分配该types的对象的地址。 alignment是实现定义的整数值,表示可以分配给定对象的连续地址之间的字节数。 对象types对该types的每个对象施加alignment要求; 可以使用alignment说明符(7.6.2)来请求更严格的alignment。
每种types都有alignment要求。 通常情况下,这种types的variables可以被有效地访问,而不必为了达到任何给定的数据types成员而导致CPU产生多个读/写访问。 此外,它还确保了整个variables的有效复制。 alignof
将返回给定types的alignment要求。
alignas
用于强制对数据types进行alignment(只要不严格alignof
所述数据types将返回的alignof
)