了解对齐概念

Understanding alignment concept

本文关键字:对齐 了解      更新时间:2023-10-16

对齐是一个实现定义的整数值,表示给定的对象。

这个概念有点不清楚。例如:

struct B { long double d; };
struct D : virtual B { char c; }

当D是一个完整对象的类型时,它将有一个子对象类型B,因此必须对long double进行适当的对齐。

这是什么意思?sizeof(long double)是在这种情况下介于什么之间的字节数??

大多数CPU都有关于数据存储位置的"首选项"。在读取或写入内存地址时,如果地址与您尝试写入的数据大小不匹配,则操作可能会较慢(或完全非法(。例如,通常要求从可被4整除的地址开始分配4字节整数。

也就是说,存储在地址7上的int要么效率较低,要么完全非法,这取决于您的CPU。但是如果它被存储在地址8,CPU是高兴的。

这就是对齐所表达的:对于任何类型为T的对象,为了满足CPU的要求,它的地址必须可以被什么整除?">

在C++中,对象的对齐由实现定义(因为如上所述,它取决于CPU架构(。C++只是说每个对象都有对齐,并描述了如何确定复合对象的对齐。

"为long double对齐"只是意味着必须分配对象,以便将其第一个字节放置在对long double有效的地址中。如果CPU体系结构将long double的对齐指定为10(例如(,那么这意味着具有此对齐的每个对象都必须分配在可被10整除的地址上。

我完全理解你的不确定性。这可能是我见过的解释什么是对齐的最糟糕的尝试之一

从实际的角度考虑。

00100000  64 65 66 61 75 6c 74 0a  31 0a 31 0a 31 0a 31 0a  |default.1.1.1.1.|
00100010  32 0a 31 0a 33 0a 30 0a  31 0a 34 0a 32 33 0a 31  |2.1.3.0.1.4.23.1|
00100020  39 0a 31 37 0a 35 0a 32  36 0a 32 34 0a 33 0a 38  |9.17.5.26.24.3.8|
00100030  0a 31 32 0a 31 31 0a 31  30 0a 31 34 0a 31 33 0a  |.12.11.10.14.13.|
00100040  38 32 0a 38 33 0a 38 34  0a                       |82.83.84.|

这是任意数据的六进制转储。假设此数据已加载到内存中的地址,如图所示。由于地址是用十六进制写的,所以很容易看到位对齐。

0x100000和0x100001处的数据可以作为16位对齐值进行访问(使用合适的CPU指令或通过C指针引用进行16位数据访问(。但是数据0x100003和0x100004没有对齐—它跨越2和3处的16位字以及4和5处的16比特字。前者是16位对齐的,而后者不是。

同样,0x100030.100037处的64位(8字节(值也是64位对齐的。但0x100038之前的一切都不是。

对准特性是由于存储器总线硬件将存储器访问组织成总线周期。16位数据总线能够在一次操作中获取8位或16位,但后者仅在地址为偶数时(最低有效地址位为零(。允许"奇数对齐"的CPU执行两个连续的总线周期(一个偶数,另一个奇数(来完成操作。其他CPU只是针对不对齐的总线周期发出故障。