c和c++数据对齐

 

一、什么是数据对齐

1、现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。

2、访问数据的地址要满足一定的条件,能被这个数据的长度所整除。 例如,1字节数据已经是对齐的,2字节的数据的地址要被2整除,4字节的数据地址要 被4整除。

3、 数据对齐并不是操作系统的内存结构的一部分,而是C P U结构的一部分。

4、 当C P U访问正确对齐的数据时,它的运行效率最高。当数据大小的数据模数的内存地址是0时,数据是对齐的。例如, W O R D值应该总是从被2除尽的地址开始,而D W O R D值应该总是从被4除尽的地址开始,如此等等。当C P U试图读取的数据值没有正确对齐时, C P U可以执行两种操作之一。即它可以产生一个异常条件,也可以执行多次对齐的内存访问,以便读取完整的未对齐数据值。

 

 

二、对齐的原因

1、 现在各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。其他平台可能没有这种情况, 但是最常见的是如果不按照适合其平台的要求对数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为 32位)如果存放在偶地址开始的地方,那么一个读周期就可以读出,而如果存放在奇地址开始的地方,就可能会需要2个读周期,并对两次读出的结果的高低 字节进行拼凑才能得到该int数据。显然在读取效率上下降很多。这也是空间和时间的博弈。

2、数据对齐是为了读取数据的效率。假如说每一次 读取数据时都是一个字节一个字节读取,那就不需要对齐了,这跟读一个字节没有什 么区别,就是多读几次。但是这样读取数据效率不高。为了提高读取数据的带宽,现 代存储系统都采用许多并行的存储芯片来提高读取效率。

 

三、数据对齐的实现

数据对齐的实现方式有两种,自然对齐(即默认对齐)和强制对齐

1)、自然对齐

 一般编译器如VS2003-VS2010,CB,DEV C++等编译器的对齐位,默认都是8位,即#pragma pack(value) value = 8。

例1:

结构体占用内存大小:认为cc为补充字节

struct A{

char _iC1; //1 + 3*cc = 4,因为下面是4个字节的

int _il; //4 + 4 = 8

char _iC2; //8 + 1 + 7*cc = 16

double _id; //16 + 8 = 24

char _iC3; //24 + 1 + 7*cc = 32,因为默认对齐位是8,必须保证整个结构体的大小是8的倍数

};

测试:

32

 

例2:

结构体占用内存大小:认为cc为补充字节

struct A{

char _iC1; //1 + 3*cc = 4,因为下面是4个字节的

int _il; //4 + 4 = 8

char _iC2; //8 + 1 + 7*cc = 16

double _id; //16 + 8 = 24

char _iC3; //24 + 1 = 25,目前是25

char _iC4; //25 + 1 + 6*cc = 32,因为25+1=26不是8的倍数,必须保证整个结构体的长度是8的倍数

};

测试:

 

32

 

2)、强制对齐,即人为修改#pragma pack(value) 中value的值

#pragma pack(4)

struct A{

char _iC1; //1+3*cc=4

int _il; //4+4=8

char _iC2; //8+1+3*cc=12 对齐位强制要求是4,所以下面虽然是8,但是从8和4中取较小值进行对齐,还是4

double _id;//12+8=20,因为对齐位强制4,所以实际上是12+4+4=20,分了两次读取

char _iC3;//20+1=21,对齐位是4,下面是1,选较小值1,

char _iC4;//21+1+2*cc=24,因为是最后一个了,整个结构体长度须为4的倍数,所以必须补2个cc

};

测试结果:

 

24

四、个人总结

1).数据对齐的定义:

访问数据的地址必须能被这个数据的长度所整除, 即地址/数据长度的余数为0,例如,1字节数据已经是对齐的,2字节的数据的地址要被2整除,4字节的数据地址要 被4整除;

2).如何实现数据对齐:

单个数据容易,多个数据组成的结构体数据对齐,即求结构体的长度:

结构体中单个元素的字节数必须要从下一个元素或者规定的对齐位(默认为8或者#pragma pack(n)来定义)中选较小值,如果是最后一个元素,则必须保证整个结构体的长度为规定对齐位数n的整数倍;

3).数据对齐的意义:

提升CPU读取数据的带宽,即可以按照规定的对齐位来读取字节;

 

参考链接:https://www.cnblogs.com/bakari/archive/2012/08/27/2658956.html

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值