【问题标题】:Why is the default alignment for `int64_t` 8 byte on 32 bit x86 architecture?为什么在 32 位 x86 架构上 `int64_t` 的默认对齐方式为 8 字节?
【发布时间】:2016-04-02 22:42:35
【问题描述】:

为什么在 32 位 x86 ABI 中 int64_t(例如 long long)的默认对齐方式是 8 字节? 4 字节对齐似乎没问题,因为它只能作为两个 4B 半来访问。

【问题讨论】:

  • stackoverflow.com/questions/1054657 的可能重复项:“通常的经验法则(直接来自 Intel 和 AMD 的优化手册)是每种数据类型都应该按照自己的大小对齐。int32应该在 32 位边界上对齐,int64 在 64 位边界上对齐,依此类推。char 适合任何地方。" A long long 大小为 64 位,因此它是使用 8 字节对齐进行最佳对齐。
  • @RemyLebeau 是的,我知道。我一直在寻找经验法则背后的推理。您链接的问题提到 32 位处理器具有 64 位数据总线,然后 8 字节对齐是有意义的。谢谢!
  • 我所知道的所有 32 位 C 和 C++ 编译器(但我没有得到太多)努力使 64 位类型与 8 对齐。这对 最重要double,当它们不对齐时访问它们是非常昂贵的,当它跨越缓存线时是胖 x3。你是否也不清楚,很奇怪 SO 用户将编译器的名称保密。
  • @HansPassant 你说的胖 x 3 是什么意思?我有 64 位编译器。我阅读了有关对齐要求的维基百科文章,并在那里提到了这一点。
  • 慢 3 倍以上。如果您使用 64 位编译器,那么关于 32 位 x86 架构的问题就完全无关紧要了。

标签: c++ x86 memory-alignment


【解决方案1】:

有趣的一点:如果您只将它作为两半加载到 32 位 GP 寄存器中,那么 4B 对齐意味着这些操作将以其自然对齐方式发生。

但是,最好将变量的两半都放在同一缓存行中,因为几乎所有访问都会读/写两半。与整个事物的自然对齐对齐可以解决这个问题,即使忽略下面的其他原因。


32 位 x86 可以使用 MMX 或 SSE2 movq 在单个 64 位加载中加载 64 位整数。只要您不需要立即常量或 mul 或 div,使用向量指令处理 64 位 add/sub/shift/ 和按位布尔值会更有效(单指令)。 64b 元素的向量指令在 32b 模式下仍然可用。


原子 64 位比较和交换也可用于 32 位模式(lock CMPXCHG8B m64 的工作方式与 64 位模式的 lock CMPXCHG16B m128 类似,使用两个隐式寄存器 (edx:eax))。 IDK 跨越缓存线边界会有什么样的惩罚。


现代 x86 CPU 对未对齐的加载/存储基本上没有任何惩罚,除非它们跨越缓存线边界,这就是为什么我只是这么说,而不是说未对齐的 64b 通常会不好。请参阅 wiki 中的链接,尤其是。 Agner Fog 的指南。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-22
    • 1970-01-01
    • 2012-01-28
    • 1970-01-01
    • 2020-10-06
    • 2013-01-31
    • 2017-06-05
    • 2015-08-03
    相关资源
    最近更新 更多