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