内存对齐

内存对齐是为了提高程序运行效率和移植性,确保数据在内存中按照特定规则排列。文章详细介绍了内存对齐的必要性,数据类型的对齐值,结构体的自身对齐值,有效对齐值的概念,并通过实例分析了不同对齐方式下的内存分布。同时讨论了C++中类继承时的内存对齐问题,强调了正确内存布局的重要性。
摘要由CSDN通过智能技术生成

1.深入内存对齐

为什么需要内存对齐呢?我们定义一个变量后,就会为该变量在某内存地址处分配一个空间。举例如下:

struct A

{

int d;

char c;

long l;

}


A a={0};//定义一个变量a.

设a 的地址为0,则a.d地址为0,a.c为4,a.l为5。如果空间真的是这样分配的话,会造成一个问题,在X86体系机器上,CPU的一次访存是直接取出32位的值。当我们写出类似 long tmp = a.l 的代码,那么,CPU将会从 a.l 这个地址开始,取出四个字节的数据。先假设内存的设计是,允许从任意地址取值,但若按“规整”的方式取值,效率更高一些。若从 内存地址 5 处开始取值,则会产生两次取值: 第一次取567三个字节的数据,第二次取8字节处的数据。因为,0123,4567,...每四个字节为一个单元,跨单元取值需要多次取。


解决这个问题的方法就是内存对齐。设想,如果任何变量均可以在一次取值内完毕,或者,每一次取值的效率都达到了百分之百(即,每次取值没有浪费的功,没有取白费的数据,如,取32个字节的数据,分为四次取,每次取8字节,这就是效率达到了百分之百),将使程序运行速度得到很大程度的加快。那么,这个过程往往需要人工的干预,即,人为的控制变量在内存中的地址。有2字节对齐,4字节对齐,8字节对齐,等等。你当然可以按任何字节来对齐,但如果要达到访存高效,就要按照内存的访问规律来对齐。之所以会出现,让人手动地指定内存对齐大小,是因为考虑到程序的移植性。多数情况下,编写的程序可能不仅仅在一种平台上运行,还可能在其它不同的平台上运行,内存分布可能不同,各个变量相对地址都可能不同(当然,整个内存模型都可能不同,模型也是从基础的字节构建起来的,我们在此只考虑内存分布细节)。但如果我们限制各个变量的摆放规则,可以使得在不同平台上内存中的变量分布都按一套规则规整化,增强了程序的移植性。这么做还有一个附带的好处,就是规整化,规律化的内存分布,加快内存访问。

现在保证了每次取一个变量都能尽可能地一次取出,由于内存访存时每次是从边界开始访存,有固定的模式,不可随机跳到“任意地址”。所以必须尽可能地将变量的开始地址置于边界,访存边界即对齐值的整数倍地址处(注意是尽可能,并不是每一个变量都对齐到了访存边界)。下面是访存的内存模型, n 是实际内存对齐数。


处理器眼里的内存

处理器访存时,只能从 xn, (x+1)n, (x+2)n ... 等 n 的整数倍地址处开始访存,且处理器一次能读出 n 个字节。

详细分析内存对齐前,先给出几个概念,

1)数据类型自身的对齐值:即类型的大小。

2)指定对齐值:人工指定的内存对齐值,如C语言可以使用#pragma pack (value)时的指定对齐值value。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值