C++:对齐方式
C++:对齐方式
C + + 的低级功能之一是能够指定内存中对象的精确对齐方式,以最大限度利用特定的硬件体系结构。 默认情况下,编译器会按大小值对类和结构成员进行对齐:在1个字节的边界上、在2字节边界上、 bool char short int 、和 long 4 字节 float long long double 边界上、、以及 long double 8 字节边界上。
在大多数情况下,你永远不需要关心对齐方式,因为默认对齐已经是最佳的。 但是,在某些情况下,您可以通过为数据结构指定自定义对齐方式来实现显著的性能改进或节省内存。 在 Visual Studio 2015 之前,可以使用 Microsoft 特定的关键字 __alignof 并 __declspec(align) 指定大于默认值的对齐方式。 从 Visual Studio 2015 开始,应使用 c + + 11 标准关键字 alignof ,并 alignas 获得最大的代码可移植性。 新关键字的行为方式与 Microsoft 特定的扩展相同。 这些扩展插件的文档也适用于新关键字。 C + + 标准不指定封装行为,以便在小于目标平台的编译器默认值的边界上对齐,因此 #pragma pack 在这种情况下仍需要使用 Microsoft。
使用aligned_storage 类通过自定义对齐方式为数据结构分配内存。 Aligned_union 类用于为具有不常用构造函数或析构函数的联合指定对齐方式。
对齐和内存地址
对齐方式是内存地址的一个属性,表示为数字地址对 2 的幂次方取模。 例如,地址0x0001103F 模数4为3。 该地址被视为与 drj-4n-yzg + 3 对齐,其中4表示所选的2的幂。 地址的对齐方式取决于所选的2的幂。 相同的地址对 8 取模为 7。 如果一个地址的对齐方式是 Xn+0,它将对齐到 X。
Cpu 执行对存储在内存中的数据执行的指令。 数据由其在内存中的地址标识。 单个基准还具有大小。 如果某个基准的地址与其大小一致,我们会将该基准自然对齐。 否则,将其称为未对齐。 例如,如果用于标识它的地址有8个字节的对齐方式,则8字节浮点基准自然对齐。
数据对齐的编译器处理
编译器会尝试使用阻止数据不一致的方式来进行数据分配。
对于简单的数据类型,编译器将分配是数据类型的大小(以字节为单位)的倍数的地址。 例如,编译器会将地址分配给类型为4的倍数的变量 long ,将地址的下2位设置为零。
编译器还以自然对齐结构的每个元素的方式来填充结构。 请考虑 struct x_ 以下代码示例中的结构:
struct x_
{
char a; // 1 byte
int b