'double' 结构成员在 32 位机器上的填充逻辑

Padding logic of 'double' struct members on 32-bits machines

根据这个 link https://www.geeksforgeeks.org/structure-member-alignment-padding-and-data-packing/ ,在数据总线大小 = 4 字节的 32 位机器上,'double' 类型的结构成员从 8 的倍数的地址开始. 但即使它们从 4 的倍数的地址开始,我们也需要 2 次加载才能将它们从内存中取出。所以我不明白起始地址是 8 的倍数的更严格限制的原因。

我绝对不是专家,所以如果我错了,我也很想知道更多,但我看到强制对 8 字节进行双对齐的一个原因是 cpu缓存。如果将双精度放在 4 字节对齐上,缓存可能只会获得双精度的一半并强制进行更多读取。通过强制对齐 8 个字节,它确保单个缓存行用于读取整个 double。

这个问题很相似,why is data structure alignment important for performance?并且给出的一些答案可能比我能更好地解释这个问题。

在链接页面呈现的模型中,没有理由将 double 的地址限制为八字节的倍数。它给出了四字节内存传输的数量作为对齐的原因,只要它们从四字节对齐的地址开始,就可以在两次传输中加载八个字节。不需要八字节对齐的地址。 (互联网上的某些网页质量不高也就不足为奇了。)

但是,对于“32 位机”或“64 位机”并没有单一的定义。处理器和系统在几个方面有所不同,包括总线宽度(因此基本内存传输大小)、处理器寄存器宽度、虚拟内存映射功能、指令集。这些中没有一个能使机器成为“32 位”或“64 位”。

处理器可能需要 double 的八字节对齐地址,这仅仅是因为它的指令集编码被设计为不具有 double 地址的低位。将 double 加载到浮点寄存器的“load double”指令可能无法在某些寻址形式中指定地址的低三位;他们总是被认为是零。

另一个问题可能是处理器主要是 32 位处理器,具有 32 位通用寄存器,但具有 64 位总线。将 32 位项加载到通用寄存器只需要四字节对齐,因为处理器总是加载一些八字节对齐的 64 位,然后取高 32 位或低 32 位。 (可能它还会在可能的情况下合并连续的 32 位加载指令,因此使用了完整的 64 位。)

如另一个答案所述,八字节对象需要八字节对齐可防止它们跨越缓存行或内存页。