字节对齐
来源:互联网 发布:建筑网络计划图 编辑:程序博客网 时间:2024/06/05 13:32
字节对齐的意义:
字节对齐是计算机系统的存储器与处理器数据交换规则。数据在存储器上存储方式决定了处理器的读取速度,对齐限制为双方制定了一个约定,简化了双方的硬件接口设计。
假如处理器一次从存储器中取4个字节,处理器每次都会在地址为4K(4的整数倍)的地址开始读取数据。
举个例子:
struct T1{ char c; short s; int i;}
sizeof(T1)结果是8字节,数据在内存中的分布如下:
如果没有字节对齐的话,需要把变量s和i前移一个字节,
而目前处理器是以4字节为单位从存储器中读取数据,后果就是读取变量i时需要读两次内存,因为变量i分布在0-3和4-7两个单元上,
这是计算机在空间和时间的博弈,损失空间换取时间。
一个结构体在内存中占多少字节?
按照字节对齐的原则,K字节的对象的地址必须是nK,结构体中的变量按照顺序,依次找到符合自己的位置(short要求2k,int要求4k,double要求8k。。。),中间没有用到的字节使用占位符,也要算到结构体的长度中。
在这里需要解释windows严格要求k字节对象的地址必须是k的倍数,linux在处理8字节的double变量时,采用了4字节对齐。
————————————————————————————————————————————————————————————————————————
除了系统提供的规则,我们可以在自己的程序制定字节对齐规则。
使用预编译指令#pragma pack (value)告诉编译器对齐数value,如下
#pragma pack(4)struct T2{short s;int i;}#pragma pack()
按照4字节对齐之后,结构体大小为8字节,结构体在内存分布如下:
#pragma pack(2)struct T3{short s;int i;}#pragma pack()
按照2字节对齐之后,结构体大小变为6字节,结构体在内存中分布如下:
需要注意的是对齐规则只对 value>sizeof(成员)的结构体成员生效,例如pack(4)并不会改变short成员存储在2K地址的规则,但是double就会从4K的地址开始存放。
使用#pragma pack编译选项应该清楚的意识到,它会为程序带来什么影响。
如果pack(1),那么结构体会依次排布占满所有的地址,这样做的好处是使用最小的地址空间,但是这样处理器在读取结构体时效率最低。
字节对齐方式与处理器地址宽度相同,这时处理器读取结构体效率最高,吞吐率也最大。
————————————————————————————————————————————————————————————————————————
一些建议:
1.定义结构体时,按照变量占用空间的大小,由大到小确定结构体中变量的顺序,这样可以既节省空间,又不损失效率。
2.网络中传递数据时,最好双方约定字节对齐方式,因为不同系统之间的字节对齐方式有可能不同。
3.当结构体中嵌套结构体时,最好不要让内存结构体把外层结构体分隔开,这样的话外层结构体字节对齐方式会被分为两种。
- 字节对齐
- 字节对齐
- 字节对齐
- 字节对齐
- 字节对齐
- 字节对齐
- 字节对齐
- 字节对齐
- 字节对齐
- 字节对齐
- 字节对齐
- 字节对齐
- 字节对齐
- 字节对齐
- 字节对齐
- 字节对齐
- 字节对齐
- 字节对齐
- nios ii 之 使用自带LCD 16207驱动1602的问题
- Nginx总结
- Word2007/2003常用快捷键大全
- 如何合理地安排窗体的启动顺序?
- 程序猿,你关心过自己的健康吗?
- 字节对齐
- base-kernel-内存映射
- Android的第一个月
- 使用AJAX检测用户名是否可用,高手一定要绕道
- sql中group by 和count 以及内连接查询的运用
- autogrow failed
- 每天要做的事情,写下来备忘。
- 在app.config中获取ConnectionStrings配置
- MAXScript蒙皮修改器(skin)用法