字节对齐方式总结

字节对齐方式总结

ID:35301768

大小:25.00 KB

页数:3页

时间:2019-03-23

字节对齐方式总结_第1页
字节对齐方式总结_第2页
字节对齐方式总结_第3页
资源描述:

《字节对齐方式总结》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库

1、前言:《***软件编程规范》中提到:“在定义结构数据类型时,为了提高系统效率,要注意4字节对齐原则……”。本文解释x86上字节对齐的机制,其他架构读者可自行试验。同时,本文对C/C++的函数调用方式进行了讨论。BTW想了几天要在休息时间写个总结但是直到今天18日才动手。写出来应该对自己还是有帮助的。也许还有一点点参考价值吧。由于本人水平所限,有不正确之处,欢迎大家提出。感谢几位同事。以及carrot。呵呵……下面言归正传。1.先看下面的例子:struct A{  char c1;  int i;  short s;  int j;}a;struct B{  int i;  int 

2、j;    short s;  char c1;}b;结构A没有遵守字节对齐原则(为了区分,我将它叫做对齐声明原则),结构B遵守了。我们来看看在x86上会出现什么结果。先打印出a和b的各个成员的地址。会看到a中,各个成员间的间距是4个字节。b中,i和j,j和s都间距4个字节,但是s和c1间距2个字节。所以:sizeof(a) = 16sizeof(b) = 12为什么会有这样的结果呢?这就是x86上字节对齐的作用。为了加快程序执行的速度,一些体系结构以对齐的方式设计,通常以字长作为对齐边界。对于一些结构体变量,整个结构要对齐在内部成员变量最大的对齐边界,如B,整个结构以4为对齐边界

3、,所以sizeof(b)为12,而不是11。对于A来讲,虽然声明的时候没有对齐,但是根据打印出的地址来看,编译器已经自动为其对齐了,所以每个成员的间距是4。在x86下,声明A与B唯一的差别,仅在于A多浪费了4个字节内存。(是不是某些特定情况下,B比A执行更快,这个还需要讨论。比如紧挨的两条分别取s和c1的指令)如果体系结构是不对齐的,A中的成员将会一个挨一个存储,从而sizeof(a)为11。显然对齐更浪费了空间。那么为什么要使用对齐呢?体系结构的对齐和不对齐,是在时间和空间上的一个权衡。对齐节省了时间。假设一个体系结构的字长为w,那么它同时就假设了在这种体系结构上对宽度为w的数据

4、的处理最频繁也是最重要的。它的设计也是从优先提高对w位数据操作的效率来考虑的。比如说读写时,大多数情况下需要读写w位数据,那么数据通道就会是w位。如果所有的数据访问都以w位对齐,那么访问还可以进一步加快,因为需要传输的地址位减少,寻址可以加快。大多数体系结构都是按照字长来对齐访问数据的。不对齐的时候,有的会出错,比如MIPS上会产生bus error,而x86则会进行多次访问来拼接得到的结果,从而降低执行效率。有些体系结构是必须要求对齐的,如sparc,MIPS。它们在硬件的设计上就强制性的要求对齐。不是因为它们作不到对齐的访问,而是它们认为这样没有意义。它们追求的是速度。上面讲了

5、体系结构的对齐。在IA-32上面,sizeof(a)为16,就是对齐的结果。下面我们来看,为什么变量声明的时候也要尽量对齐。我们看到,结构A的声明并不对齐,但是它的成员地址仍是以4为边界对齐的(成员间距为4)。这是编译器的功劳。因为我所用的编译器gcc,默认是对齐的。而x86可以处理不对齐的数据访问,所以这样声明程序并不会出错。但是对于其他结构,只能访问对齐的数据,而编译器又不小心设置了不对齐的选项,则代码就不能执行了。如果按照B的方式声明,则不管编译器是否设置了对齐选项,都能够正确的访问数据。目前的开发普遍比较重视性能,所以对齐的问题,有三种不同的处理方法:1)    采用B的方

6、式声明2)    对于逻辑上相关的成员变量希望放在靠近的位置,就写成A的方式。有一种做法是显式的插入reserved成员:         struct A{           char c1;           char reserved1[3];           int i;           short s;           char reserved2[2];           int j;}a;3)    随便怎么写,一切交给编译器自动对齐。代码中关于对齐的隐患,很多是隐式的。比如在强制类型转换的时候。下面举个例子:unsigned int ui_1=0x

7、12345678;unsigned char *p=NULL;unsigned short *us_1=NULL;p=&ui_1;*p=0x00;us_1=(unsigned short *)(p+1);*us_1=0x0000;最后两句代码,从奇数边界去访问unsigned short型变量,显然不符合对齐的规定。在x86上,类似的操作只会影响效率,但是在MIPS或者sparc上,可能就是一个bus error(我没有试)。有些人喜欢通过移动指针来操作结构中的成员(

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。