32位Intel处理器上的内存对齐

时间:2009-06-28 10:18:52

标签: memory x86 alignment 32-bit intel

Intel的32位处理器(如Pentium)具有64位宽的数据总线,因此每次访问可获取8个字节。基于此,我假设这些处理器在地址总线上发出的物理地址总是8的倍数。

首先,这个结论是否正确?

其次,如果它是正确的,那么应该将数据结构成员对齐在8字节边界上。但我见过人们在这些处理器上使用4字节对齐。

他们如何才能证明这样做?

5 个答案:

答案 0 :(得分:14)

通常的经验法则(直接来自英特尔和AMD的优化手册)是每种数据类型都应该按照自己的大小对齐。 int32应在32位边界上对齐,在64位边界上对齐int64,依此类推。在任何地方都可以使用char。

另一个经验法则当然是“编译器已被告知对齐要求”。您无需担心它,因为编译器知道添加正确的填充和偏移以允许有效访问数据。

唯一的例外是使用SIMD指令时,您必须手动确保大多数编译器的对齐。

  

其次,如果它是正确的,那么一个   应该对齐数据结构成员   一个8字节的边界。但我见过   人们使用4字节对齐方式   而是在这些处理器上。

我不知道这有什么不同。 CPU可以简单地为包含这4个字节的64位块发出读取。这意味着它要么在请求的数据之前或之后获得4个额外的字节。但在这两种情况下,它只需要一次读取。 32位数据的32位对齐确保它不会跨越64位边界。

答案 1 :(得分:6)

物理总线是64位宽... 8的倍数 - >是

但是,还有两个因素需要考虑:

  1. 某些x86指令集是字节寻址的。有些是32位对齐的(这就是为什么你有4字节的东西)。但是没有(核心)指令是64位对齐的。 CPU可以处理未对齐的数据访问。
  2. 如果你关心性能,你应该考虑缓存行,而不是主内存。缓存行要宽得多。

答案 2 :(得分:2)

这样做是合理的,因为改为8字节对齐将构成ABI变化,并且边际性能改进不值得麻烦。

正如其他人已经说过的,高速缓存很重要。实际内存总线上的所有访问都是根据高速缓存行(x86上的64字节,IIRC)。请参阅已经提到的“每位程序员需要了解的关于内存的内容”文档。所以实际的内存流量是64字节对齐的。

答案 3 :(得分:1)

对于随机访问,只要数据没有错位(例如越过边界),我认为这不重要;可以使用硬件中的简单AND构造找到数据中的正确地址和偏移量。当一个读取访问不足以获得一个值时,它会变慢。这也是编译器通常将小值(字节等)放在一起的原因,因为它们不必处于特定的偏移量; short应该在偶数地址上,4字节地址为32位,8字节地址为64位。

请注意,如果您具有缓存调用和线性数据访问权限,则情况会有所不同。

答案 4 :(得分:1)

您引用的64位总线为缓存提供信息。作为CPU,始终读写整个缓存行。高速缓存行的大小始终是8的倍数,其物理地址确实以8字节偏移量对齐。

高速缓存到寄存器的传输不使用外部数据总线,因此该总线的宽度无关紧要。