繁体   English   中英

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

[英]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的倍数 - >是

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

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

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM