了解对齐概念

时间:2014-07-15 18:26:26

标签: c++ memory-alignment

  

alignment是表示实现定义的整数值   给定的连续地址之间的字节数   对象可以分配。

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

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

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

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

2 个答案:

答案 0 :(得分:6)

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

也就是说,存储在地址int上的7效率较低,或完全非法,具体取决于您的CPU。但如果它存储在地址8,则CPU很高兴。

这就是对齐表达的内容:对于T类型的任何对象,为了满足CPU的要求,它的地址必须能被整除吗?“

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

“为long double对齐”只是意味着必须分配对象,以便将其第一个字节放在对long double有效的地址中。如果CPU体系结构指定long double的对齐方式为10(例如),则表示必须在可被10整除的地址上分配具有此对齐方式的每个对象。

答案 1 :(得分:1)

我完全理解你的不确定性。这可能是我所看到的解释对齐方式的最糟糕尝试之一。

从实际角度考虑它。

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没有对齐 - 它跨越16位字2和3,16位字位于4和5.前者是16位对齐而后者不是。

同样,0x100030..100037处的64位(8字节)值是64位对齐的。但是直到0x100038都没有。

对齐特性归因于存储器总线硬件,它将存储器访问组织到总线周期中。 16位数据总线能够在一次操作中获取8位或16位,但后者仅在地址为偶数(最低有效地址位为零)时才能获取。允许"奇数对齐的CPU#34;执行两个连续的总线周期(一个甚至另一个总线周期)以完成操作。其他CPU只为非对齐总线周期发出故障。