数据对齐

来源:互联网 发布:暖通工程预算软件 编辑:程序博客网 时间:2024/05/09 10:13

数据对齐

  简单来说,数据对齐就是指计算机系统要求某个类型的对象的地址必须是某个值K(通常是2、4或8)的整数倍。举个栗子:

struct st1{    char a;    int i;}

  假设st1的地址为A,那么st1.a的地址为A,而st1.i的地址为A+4,在st1.a与st1.i之间的3个字节将会被填0。这种对齐限制简化了形成处理器和内存系统之间接口的硬件设计。各平台处理器对内存系统的处理有所不同。有些平台规定只能从偶数地址存取数据,如果数据对象不是以2字节对齐存放的化,就可能导致系统无法工作。大部分平台不会只支持这么死板的操作,他们可能规定一次存取8(或其他)字节数据,这种情况下,如果一个double类型的数据正好存在了地址对齐为8的地方,那么处理器一次就可以取出完整的数据,而如果该数据正好有4字节落在了前一块对齐为8的地址的后4字节(如4-7字节处),另外4字节落在了后一块对齐为8的地址的前4字节(如8-11字节处),那么处理器就要分两次操作才能取出这个数据,这明显降低了系统性能。

  在x86-64平台下,无论数据是否对齐,系统都能正常工作。但GCC和Intel的编译器都建议进行数据对齐以提高内存系统的性能。GCC是固定的4字节对齐。而Intel的对齐原则是任何K字节的基本对象的地址必须是K的倍数,可以看到这条对齐原则会得到如下对齐:

K 类型 1 char 2 short 4 int,float 8 long,double,char*

  编译器在汇编代码中放入指令,指明全局数据所需的对齐,如:.align 8,这就保证了它后面的数据的起始地址是8的倍数。

  对于包含结构的代码,编译器会在需要的字段之间插入0来使数据达到对齐的效果,比如开头的例子st1。在结构体、联合或类等结构化数据类型中,数据对齐的原则是向其包含的基本类型中最长的那个类型对齐,如开头的例子是向int类型所对应的4字节对齐,而在下面的例子中:

struct st2{    char    *a;    short   b;    double  c;    char    d;    int     e;}

  此时应向8字节对齐。对于这个例子,它的各字段偏移如下:

  此时共占用了32字节,为了减少浪费,可以重新排列元素,对于数据元素长度都是2的幂时,一种行之有效的策略是按照大小降序排列,导致如下声明:

struct st2{    char    *a;    double  c;    int     e;    short   b;    char    d;}

  此时共占用了24字节,如下:

原创粉丝点击