我现在正在使用共享内存。
我无法理解alignof
和alignas
。
cppreference不清楚:alignof
返回“ alignment”,但是什么是“ alignment”?要为下一个要对齐的块添加的字节数?填充尺寸?堆栈溢出/博客条目也不清楚。
有人能解释清楚alignof
和alignas
?
我现在正在使用共享内存。
我无法理解alignof
和alignas
。
cppreference不清楚:alignof
返回“ alignment”,但是什么是“ alignment”?要为下一个要对齐的块添加的字节数?填充尺寸?堆栈溢出/博客条目也不清楚。
有人能解释清楚alignof
和alignas
?
alignof
页面对齐的概念(现在,在进行中的对象页面上)。我看不到cplusplus.com的相关性。
Answers:
对齐方式是可以存储值的第一个字节的存储位置的限制。(需要提高处理器的性能并允许使用仅对具有特定对齐方式的数据起作用的某些指令,例如,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是一种提前了解基本数据类型的最小对齐要求的好方法(对于char,它可能会返回1,对于float等会返回4)。
仍然合法:
alignas(alignof(float)) float SqDistance;
然后将对齐方式为16的内容放置在下一个可用地址上,该地址是16的倍数(上次使用的地址可能存在隐式填充)。
sizeof
,alignof
只能应用于type-id
。
alignof()
(与对方alignas()
)在编译时评估,因此没有运行时开销?
struct
的结构和成员static
。alignas
事实证明,它比更加挑剔__attribute__((aligned))
,尤其是在像Clang这样的编译器下。
对齐方式不是填充(尽管有时会引入填充来满足对齐要求)。它是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的幂为模的数字地址。例如,地址0x0001103F以4的幂为模。该地址被称为与4n + 3对齐,其中4表示所选的幂2.地址的对齐方式取决于所选的2的幂。相同的地址模8为7。如果地址的对齐方式为Xn + 0,则称地址与X对齐。
以上声明可在Microsoft c ++参考上找到。
如果数据项的地址与大小对齐,则该数据项自然对齐,否则未对齐。例如:如果一个大小为4字节的整数变量存储在对齐4的地址中,那么我们可以说该变量自然对齐,即该变量的地址应为4的倍数。
编译器始终尝试避免未对准。对于简单的数据类型,选择的地址应为变量大小(以字节为单位)的倍数。在结构自然对齐和访问的情况下,编译器也应适当填充,此处结构将与结构中不同数据项的最大大小对齐。例如:
struct abc
{
int a;
char b;
};
在这里,结构abc对齐为4,这是int成员的大小,它显然大于1个字节(char成员的大小)。
Alignas
该说明符用于将用户定义的类型(如结构,类等)与2的幂的特定值对齐。
对齐
这是一种获取结构或类类型所对应的值的运算符。例如:
#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
}