据我所知,需要一个结构的成员之间,以确保各个类型的正确对准填充。 然而,为什么数据结构必须最大成员的对齐的倍数? 我不明白的是需要在最后的填充。
参考: http://en.wikipedia.org/wiki/Data_structure_alignment
据我所知,需要一个结构的成员之间,以确保各个类型的正确对准填充。 然而,为什么数据结构必须最大成员的对齐的倍数? 我不明白的是需要在最后的填充。
参考: http://en.wikipedia.org/wiki/Data_structure_alignment
好问题。 考虑这个假设的类型:
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位数据总线,撇开的方式做。 不仅将未对准堵塞与额外的读取总线(由于以前一样跨界),但它也将迫使寄存器转移字节,因为他们进来,更糟糕的是,错位往往混淆优化逻辑(至少,英特尔优化手册说,这样做,虽然我这最后一点的没有个人的知识)。 因此,不对是从性能的角度非常糟糕。
它通常是值得浪费填充字节这些原因。
更新:下面的评论都是有用的。 我建议他们。
对于不同的硬件上,对齐可能有必要或只是帮助加快执行。
有一定数量的处理器(ARM我相信),其中对齐访问导致硬件异常。 干净利落。
尽管典型的x86处理器是较为宽松的,还有在访问未对齐的基本类型的一个点球,因为处理器必须做更多的工作能够操作它之前把位到寄存器。 编译器包装希望仍然在通常提供特定的属性/编译指示。
由于虚拟寻址。
“......一个页面大小的边界上对齐页通过在地址替换高位,而不是做复杂的算术让硬件映射虚拟地址到物理地址。”
顺便说一句,我发现这个维基百科页面相当写得很好。
如果CPU的寄存器长度为32位,那么它可以抓住存储器是与单个汇编指令的32个边界。 它是慢抢到32位,然后拿到始于8位字节。
BTW:有没有被填充。 您可以要求结构进行包装。