为什么在 32 位 x86 架构上 `int64_t` 的默认对齐方式是 8 字节?
Why is the default alignment for `int64_t` 8 byte on 32 bit x86 architecture?
为什么在 32 位 x86 ABI 中 int64_t
(例如 long long
)的默认对齐方式为 8 字节? 4 字节对齐似乎没问题,因为它只能作为两个 4B 的一半来访问。
有趣的一点:如果你只将它作为两半加载到 32 位 GP 寄存器中,那么 4B 对齐意味着这些操作将以它们的自然对齐方式发生。
但是,最好是变量的两半都在同一缓存行中,因为几乎所有访问都会读/写两半。对齐到整个事物的自然对齐方式就可以解决这个问题,甚至可以忽略下面的其他原因。
32 位 x86 可以使用 MMX 或 SSE2 movq
在单个 64 位加载中加载 64 位整数。使用矢量指令处理 64 位 add/sub/shift/ 和按位布尔值更有效(单指令),只要您不需要立即数或 mul 或 div。具有 64b 元素的矢量指令在 32b 模式下仍然可用。
Atomic 64 位 compare-and-exchange 也可用于 32 位模式(lock CMPXCHG8B m64
与 64 位模式的 lock CMPXCHG16B m128
一样工作,使用两个隐式寄存器 (edx:eax))。 IDK 跨越 cache-line 边界会有什么样的惩罚。
现代 x86 CPU 基本上没有对错位 loads/stores 的惩罚,除非它们跨越 cache-line 边界,这就是为什么我只这么说,而不是说错位 64b 通常会很糟糕.请参阅 x86 wiki 中的链接,尤其是。 Agner Fog 的向导。
为什么在 32 位 x86 ABI 中 int64_t
(例如 long long
)的默认对齐方式为 8 字节? 4 字节对齐似乎没问题,因为它只能作为两个 4B 的一半来访问。
有趣的一点:如果你只将它作为两半加载到 32 位 GP 寄存器中,那么 4B 对齐意味着这些操作将以它们的自然对齐方式发生。
但是,最好是变量的两半都在同一缓存行中,因为几乎所有访问都会读/写两半。对齐到整个事物的自然对齐方式就可以解决这个问题,甚至可以忽略下面的其他原因。
32 位 x86 可以使用 MMX 或 SSE2 movq
在单个 64 位加载中加载 64 位整数。使用矢量指令处理 64 位 add/sub/shift/ 和按位布尔值更有效(单指令),只要您不需要立即数或 mul 或 div。具有 64b 元素的矢量指令在 32b 模式下仍然可用。
Atomic 64 位 compare-and-exchange 也可用于 32 位模式(lock CMPXCHG8B m64
与 64 位模式的 lock CMPXCHG16B m128
一样工作,使用两个隐式寄存器 (edx:eax))。 IDK 跨越 cache-line 边界会有什么样的惩罚。
现代 x86 CPU 基本上没有对错位 loads/stores 的惩罚,除非它们跨越 cache-line 边界,这就是为什么我只这么说,而不是说错位 64b 通常会很糟糕.请参阅 x86 wiki 中的链接,尤其是。 Agner Fog 的向导。