C语言中的内存对齐

  • Post author:
  • Post category:其他




内存对齐的方法:


1、 对于结构的各个成员,第一个成员位于

偏移为0

的位置,以后每个数据成员的

偏移量

必须是

min(#pragma pack()指定的数,这个数据成员的自身长度) 的倍数。






2、 在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照

#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的

那个进行。




3

、对齐后的长度必须是

成员中最大的对齐参数的整数倍

,这样在处理数组时可以保证每一项都是边界对齐。





内存对齐的主要作用是:


1、 平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。




2、 性能原因:经过内存对齐后,CPU的内存访问速度大大提升。





图一:






这是普通程序员心目中的内存印象,由一个个的字节组成,而CPU并不是这么看待的。

图二:



CPU把内存当成是一块一块的,块的大小可以是2,4,8,16字节大小,因此CPU在读取内存时是一块一块进行读取的。

假设CPU要读取一个int型4字节大小的数据到寄存器中,分两种情况讨论:

1、数据从0字节开始

2、数据从1字节开始

再次假设内存读取粒度为4。

图三:

当该数据是从0字节开始时,很CPU只需读取内存一次即可把这4字节的数据完全读取到寄存器中。

当该数据是从1字节开始时,问题变的有些复杂,此时该int型数据不是位于内存读取边界上,这就是一类内存未对齐的数据。

图四:



此时CPU先访问一次内存,读取0—3字节的数据进寄存器,并再次读取4—5字节的数据进寄存器,接着把0字节和6,7,8字节的数据剔除,最后合并1,2,3,4字节的数据进寄存器。对一个内存未对齐的数据进行了这么多额外的操作,大大降低了CPU性能。

这还属于乐观情况了,上文提到内存对齐的作用之一为平台的移植原因,因为以上操作只有有部分CPU肯干,其他一部分CPU遇到未对齐边界就直接罢工了。

http://blog.csdn.net/embeddedman/article/details/7429976



版权声明:本文为SYP35原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。