Intel的32位处理器(如Pentium)具有64位宽的数据总线,因此每次访问可获取8个字节。基于此,我假设这些处理器在地址总线上发出的物理地址总是8的倍数。
首先,这个结论是否正确?
其次,如果它是正确的,那么应该将数据结构成员对齐在8字节边界上。但我见过人们在这些处理器上使用4字节对齐。
他们如何才能证明这样做?
答案 0 :(得分:14)
通常的经验法则(直接来自英特尔和AMD的优化手册)是每种数据类型都应该按照自己的大小对齐。 int32
应在32位边界上对齐,在64位边界上对齐int64
,依此类推。在任何地方都可以使用char。
另一个经验法则当然是“编译器已被告知对齐要求”。您无需担心它,因为编译器知道添加正确的填充和偏移以允许有效访问数据。
唯一的例外是使用SIMD指令时,您必须手动确保大多数编译器的对齐。
其次,如果它是正确的,那么一个 应该对齐数据结构成员 一个8字节的边界。但我见过 人们使用4字节对齐方式 而是在这些处理器上。
我不知道这有什么不同。 CPU可以简单地为包含这4个字节的64位块发出读取。这意味着它要么在请求的数据之前或之后获得4个额外的字节。但在这两种情况下,它只需要一次读取。 32位数据的32位对齐确保它不会跨越64位边界。
答案 1 :(得分:6)
物理总线是64位宽... 8的倍数 - >是
但是,还有两个因素需要考虑:
答案 2 :(得分:2)
这样做是合理的,因为改为8字节对齐将构成ABI变化,并且边际性能改进不值得麻烦。
正如其他人已经说过的,高速缓存很重要。实际内存总线上的所有访问都是根据高速缓存行(x86上的64字节,IIRC)。请参阅已经提到的“每位程序员需要了解的关于内存的内容”文档。所以实际的内存流量是64字节对齐的。
答案 3 :(得分:1)
对于随机访问,只要数据没有错位(例如越过边界),我认为这不重要;可以使用硬件中的简单AND构造找到数据中的正确地址和偏移量。当一个读取访问不足以获得一个值时,它会变慢。这也是编译器通常将小值(字节等)放在一起的原因,因为它们不必处于特定的偏移量; short应该在偶数地址上,4字节地址为32位,8字节地址为64位。
请注意,如果您具有缓存调用和线性数据访问权限,则情况会有所不同。
答案 4 :(得分:1)
您引用的64位总线为缓存提供信息。作为CPU,始终读写整个缓存行。高速缓存行的大小始终是8的倍数,其物理地址确实以8字节偏移量对齐。
高速缓存到寄存器的传输不使用外部数据总线,因此该总线的宽度无关紧要。