32位机器上“双”结构成员的填充逻辑[重复]

Posted

技术标签:

【中文标题】32位机器上“双”结构成员的填充逻辑[重复]【英文标题】:Padding logic of 'double' struct members on 32-bits machines [duplicate] 【发布时间】:2021-10-28 17:11:25 【问题描述】:

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

【问题讨论】:

【参考方案1】:

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

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

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

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

作为另一个答案,要求八字节对象的八字节对齐可以防止它们跨越缓存行或内存页面。

【讨论】:

【参考方案2】:

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

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

【讨论】:

以上是关于32位机器上“双”结构成员的填充逻辑[重复]的主要内容,如果未能解决你的问题,请参考以下文章

在 .NET 项目中同时引用 32 位和 64 位 dll 并单击一次 [重复]

32位系统上的Wow64:还原[重复]

如何找到操作系统位类型[重复]

有啥方法可以控制 C++ 中结构成员(包括位字段)之间的填充?

基本数据类型

安装的jvm是64位或32位[重复]