关于数据对齐(Data Alignment)
来源:互联网 发布:淘宝子账号怎么添加 编辑:程序博客网 时间:2024/05/29 16:08
关于数据对齐 About Data Alignment
数据对齐的由来
1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2、性能原因:为了访问未对齐的内存,处理器需要作多次内存访问,然而,对齐的内存访问仅需要一次访问。这对于效率而言有一定的下降。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)存放在偶地址开始的地方 ,那么读一个周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要读2个周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。
相关概念
1)数据类型自身的对齐值:基本数据类型的自身对齐值,等于sizeof(基本数据类型)。(在不同的平台下有可能不同,如Windows下的数据对齐即为任何K字节基本对象的地址都必须是K的整数倍,而在linux32位下,沿用的对齐策略是,2字节的数据类型的地址必须是2的倍数,而较大的数据类型如 int int* float double 的地址是4的倍数。)
2)指定对齐值:#pragma pack (value)时的指定对齐值value。
3)结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。
4)数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中较小的那个值。
有效对齐值N是最终用来决定数据存放地址方式的值,最重要。有效对齐N,就是表示“对齐在N上”,也就是说该数据的”存放起始地址%N=0”.而数据结构中的数据变量都是按定义的先后顺序来排放的。第一个数据变量的起始地址就是数据结构的起始地址。结构体的成员变量要对齐排放,结构体本身也要对齐对自身的对齐值,就是结构体成员变量占用总长度需要是对结构体有效对齐值的整 数倍。
数据对齐测试
保持数据对齐可以提高效率,其代价就是损耗了一部分的内存空间,典型的是通过空间来换取时间的案例。
数据对齐和平台是紧密相关的,不同平台下的对齐原则也不尽相同,首先介绍Windows下的数据对齐:
1.默认情况下,任何K字节基本对象的地址都必须是K的整数倍。
通常情况下,基本数据类型的字节数目为下:(然而并不是绝对的,如int类型,C标准只要求其最小拥有16位,即两个字节)
char 1
short 2
int 4
unsigned 4
long 8
unsigned long 8
float 4
doule 8
void * 4
long double 8
同时需要注意的是,在许多平台下long double实际上需要10个字节,但实际中会分配12(32位下)或者是16(64位下)个字节,这是为了读取效率。但在vs2010下测试时发现long double是8字节。
在vs2010下进行测试,选定”结构成员对齐”为默认设置,此时则按照默认对齐规则进行字节对齐。即任何K字节基本对象的地址都必须是K的倍数。假设下面每个结构体的起始地址均为0。
struct s //偏移量 //数据内容字节数 //填充的字节数 //数据对齐值 { char c; //0 //1 //7 //1 double d; //8 //8 //0 //8 }; //结构体字节大小:16 结构体对齐值:8 struct s1 //偏移量 //数据内容字节数 //填充的字节数 //数据对齐值 { char c; //0 //1 //7 //1 double d; //8 //8 //0 //8 int i; //16 //4 //4 //4 }; //结构体字体大小:24 结构体对齐值:8 (整个结构体的对齐为8,所以需要最后需要填充4个字节)) struct s2 //偏移量 //数据内容字节数 //填充的字节数 //数据对齐值 { char c; //0 //1 //3 //1 int d; //4 //4 //0 //4 char i; //8 //1 //3 //1 }; //结构体字体大小:12 结构体对齐值:4 (整个结构体的对齐为4,所以需要最后需要填充3个字节)) struct s3 //偏移量 //数据内容字节数 //填充的字节数 //数据对齐值 { char c; //0 //1 //3 //1 int i; //4 //4 //0 //4 double d; //8 //8 //0 //8 }; //结构体字节大小:16 结构体对齐值:8 struct s4 //偏移量 //数据内容字节数 //填充的字节数 //数据对齐值 { char c; //0 //1 //7 //1 long double d; //8 //8 //0 //8 }; //结构体字节大小:16 结构体对齐值:8
上述结构体对齐情况是在没有指定对齐值的情况下测试的,有效对齐值就是基本数据类型的字节数,如果指定了对齐值,有效对齐值则为自身对齐值和指定对齐值之间最小的那个。如指定对齐值为4,对于 char(1字节),short(2字节),int(4字节),以及指针(32位下指针为4字节大小),均无影响,但是对于double(8字节大小),long int(8字节大小)等,其有效对齐值为4,不再是自身对齐值的8。
在此情况下,上述结构体的大小如下
struct s //偏移量 //数据内容字节数 //填充的字节数 //数据对齐值 { char c; //0 //1 //3 //1 double d; //4 //8 //0 //4 }; //结构体字节大小:12 结构体对齐值:4 struct s1 //偏移量 //数据内容字节数 //填充的字节数 //数据对齐值 { char c; //0 //1 //3 //1 double d; //4 //8 //0 //8 int i; //12 //4 //0 //4 }; //结构体字体大小:16 //结构体对齐值:4 struct s2 //偏移量 //数据内容字节数 //填充的字节数 //数据对齐值 { char c; //0 //1 //3 //1 int d; //4 //4 //0 //4 char i; //8 //1 //3 //1 }; //结构体字体大小:12 结构体对齐值:4 (整个结构体的对齐为4,所以需要最后需要填充3个字节)) struct s3 //偏移量 //数据内容字节数 //填充的字节数 //数据对齐值 { char c; //0 //1 //3 //1 int i; //4 //4 //0 //4 double d; //8 //8 //0 //4 }; //结构体字节大小:16 结构体对齐值:4 struct s4 //偏移量 //数据内容字节数 //填充的字节数 //数据对齐值 { char c; //0 //1 //3 //1 long double d; //4 //8 //0 //4 }; //结构体字节大小:12 结构体对齐值:4
两种情况下,只有结构体s3的信息完全一致,其他结构体都有着一定的差别。
其他
上述介绍的情况是在32位下,在64位下,默认的对齐规则(无论linux或者是windows下均是任何K字节的基本数据类型的对齐值均为K),若指定了对齐值,实际对齐值仍是自身对齐值和指定对齐值的最小值。
除此之外,有两点需要注意:
1. 指针的数据大小为8字节,而不是4字节
2. long double的数据大小为16字节。
结构体对齐的实例可以根据32位下的情况进行类似的分析。
- 关于数据对齐(Data Alignment)
- About Data Alignment(关于数据对齐)
- 数据对齐说明(Data Alignment)
- 关于结构体数据对齐(About data alignment)
- 字节对齐(Data Alignment)
- 数据的字节对齐(data structure alignment)
- Data Alignment 数据对齐 from MSDN
- 数据对齐(alignment & endian)
- 数据的对齐(alignment)
- 内存对齐(Data Structure Alignment)
- 内存数据对齐(翻:Data alignment:straighten up and fly right)
- 关于栈对齐(stack alignment)
- 对齐(alignment)
- 字节对齐(Alignment)
- 分区对齐(Partition alignment)
- 内存对齐(Memory Alignment)
- Data Alignment
- Data alignment
- Android/Java日志打印工具类
- 推荐JAVA学习路线
- 窗体之间数据的传递
- Hibernate 一级缓存和二级缓存的理解
- Oracle强制转换函数
- 关于数据对齐(Data Alignment)
- IDEA构建Alluxio最新源码阅读环境
- iOS APP配置HTTPS流程
- tensorflow tutorials(七):用tensorflow实现卷积神经网络(Convolutional Neural Networks)
- JFrame实现输入数据运算输出数据
- java基础之引用与解引用
- 5670
- TCP报文格局详解
- Oracle数据精确度