c++ - 为什么结构的大小需要是任何结构成员的最大对齐的倍数

标签 c++ memory-alignment

我了解结构成员之间的填充,以确保各个类型的正确对齐。但是,为什么数据结构必须是最大成员对齐的倍数?我不明白最后需要填充。

引用: http://en.wikipedia.org/wiki/Data_structure_alignment

最佳答案

好问题。考虑这种假设类型:

struct A {
    int n;
    bool flag;
};

因此,A 类型的对象应该占用五个字节(int 占四个字节,bool 占一个字节),但实际上它占用了八个字节。为什么?

如果你使用这样的类型,就会看到答案:

const size_t N = 100;
A a[N];

如果每个 A 只有五个字节,那么 a[0] 会对齐,但是 a[1], a[ 2] 而大多数其他元素不会。

但为什么对齐如此重要?有几个原因,都与硬件有关。一个原因是最近/经常使用的内存被缓存在 CPU 芯片上的缓存行中以便快速访问。小于缓存行的对齐对象总是适合一行(但请参阅下面附加的有趣评论),但未对齐的对象可能跨越两行,浪费缓存。

实际上还有更根本的硬件原因,与字节可寻址数据在 32 位或 64 位数据总线上传输的方式有关,与缓存行完全不同。不对齐不仅会用额外的读取阻塞总线(由于之前的跨接),而且还会迫使寄存器在字节进入时移位。更糟糕的是,不对齐往往会混淆优化逻辑(至少,英特尔的优化手册说它确实如此,尽管我对最后一点没有个人知识)。因此,从性能的角度来看,错位非常糟糕。

出于这些原因,浪费填充字节通常是值得的。

更新:下面的评论都很有用。我推荐他们。

关于c++ - 为什么结构的大小需要是任何结构成员的最大对齐的倍数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10309089/

相关文章:

c++ - 同时读取两个文件

c - read(2)ing 结构时如何正确避免 "cast increases required alignment"警告?

c++ - 以下程序片段的可能输出?

c++ - 使用隐式字符串转换运算符的危险?

c++ - 为什么 p1007r0 std::assume_aligned 不需要结语?

c++ - 将二进制字节 (char*) 转换为 uint64_t*,安全吗?

c++ - 结构大小和内存布局取决于#pragma pack

c - 在打包结构的末尾对齐

c++ - 将包含主函数的 C 程序包装到 C++ 类中,

从 Visual Studio 2010 迁移到 2012 时的 C++11 问题