为什么该结构的大小需要是任何结构成员的最大对齐的倍数(why does size of the st

2019-07-29 03:00发布

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

参考: http://en.wikipedia.org/wiki/Data_structure_alignment

Answer 1:

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

struct A {
    int n;
    bool flag;
};

因此,类型的对象, A应该采取的五个字节(四为INT加上一个用于布尔),但实际上它需要八。 为什么?

如果你使用的类型类似这样的答案是看出:

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

如果每个A只有五个字节,则a[0]将保持一致,但a[1] a[2]和大多数其他元素不会。

但是,为什么对齐甚至重要吗? 有几个原因,所有的硬件相关。 原因之一是,最近/经常使用的内存中的CPU硅快速访问的高速缓存行缓存。 对准的对象比高速缓存行较小总适合于单条线(但参见下文所附有趣的评论),但是未对齐的对象可以跨两行,浪费缓存。

实际上有更根本的原因的硬件,具有字节寻址数据从缓存线转移下来一个32位或64位数据总线,撇开的方式做。 不仅将未对准堵塞与额外的读取总线(由于以前一样跨界),但它也将迫使寄存器转移字节,因为他们进来,更糟糕的是,错位往往混淆优化逻辑(至少,英特尔优化手册说,这样做,虽然我这最后一点的没有个人的知识)。 因此,不对是从性能的角度非常糟糕。

它通常是值得浪费填充字节这些原因。

更新:下面的评论都是有用的。 我建议他们。



Answer 2:

对于不同的硬件上,对齐可能有必要或只是帮助加快执行。

有一定数量的处理器(ARM我相信),其中对齐访问导致硬件异常。 干净利落。

尽管典型的x86处理器是较为宽松的,还有在访问未对齐的基本类型的一个点球,因为处理器必须做更多的工作能够操作它之前把位到寄存器。 编译器包装希望仍然在通常提供特定的属性/编译指示。



Answer 3:

由于虚拟寻址。

“......一个页面大小的边界上对齐页通过在地址替换高位,而不是做复杂的算术让硬件映射虚拟地址到物理地址。”

顺便说一句,我发现这个维基百科页面相当写得很好。



Answer 4:

如果CPU的寄存器长度为32位,那么它可以抓住存储器是与单个汇编指令的32个边界。 它是慢抢到32位,然后拿到始于8位字节。

BTW:有没有被填充。 您可以要求结构进行包装。



文章来源: why does size of the struct need to be a multiple of the largest alignment of any struct member