关于字节对齐的理解

字节对齐的剖析

一、需要了解的名词和概念

1、数据类型自身的对齐值:即数据本身所占字节长度。

2、结构体或类的自身对齐值:即其中数据成员类型对齐值的最大值。

3、指定对齐值:由编程人员通过#pragma pack(value)指定的value值,通过#pragma pack()代码解除。

4、结构体、类、数据成员的有效对齐值:即2、3以及当前计算机总线长度三者的最大值。

5、圆整: 即结构体成员变量占用总长度需要是对结构体有效对齐值的整数倍

以上为理解字节对齐的最基本要求,请耐心看完。

二、CPU的指令运行过程

在讨论字节对齐之前先简单看一下CPU对指令处理读写指令的工作过程:首先CPU从PC(程序计数器)中得到指令地址,通过总线从内存中取出指令(即其操作码+地址码),放入IR(指令寄存器)中(PC->AR[地址寄存器]->bus->DR[数据寄存器]->IR)对操作码进行译码,得到具体操作,同时PC自增1(下一条指令)。上述过程消耗一个CPU周期(机器周期)。然后进入下一个CPU周期,CPU取出其操作对象的地址码,通过总线在内存中定位到该地址,若此时为写操作,则直接将数据写入到内存地址中,操作结束,若为读操作,则需要多消耗一个CPU周期将数据通过总线从内存中取到CPU中,然后交由累加器或者其他控制元件进行处理。总之,读操作要比写操作多消耗一倍时间。

三、字节对齐的案例和分析

上述介绍看似和字长对齐没有任何关系,首先是为了让大家对CPU处理数据读写有个全面的认识,其次我们可以知道如果减少数据读取次数显然可以提高数据处理效率。

那么所谓的字节对齐就是起此作用的,宏观上来讲,它是通过一次读取有效对齐值来避免不必要的读操作,核心思想是使用空间去置换时间。

相信很多人在对结构体使用sizeof运算符(or关键字)的时候出现的那种大于其内部元素字节长度之和的现象很是费解,这其实就是因为字节对齐的原因,我们来看一个例子

struct A

{

int a1;

char a2;

short a3;

};

struct B

{

char b2;

int b1;

short b3;

};

intmain()

{

A a;

B b;

cout<<sizeof(a)<<‘‘<<sizeof(b)<<endl;

system("pause");

return 0;

}

运行结果

注:这里使用dev进行编译,如果使用VC会编译时自动进行优化

分析一下原因:为了使程序更快速的对内存中数据进行操作,势必需要减少访存时间,显然只要尽可能多地(贪心思想)取出存放的数据就能达到这一目的,所以在存储结构体中数据时默认会按照最大的长度填充字段(不足补空,同时长度受限于系统总线长度)。这样一来,A结构中,int为4字节,char+short为3字节,另外补足一个为空的字节,共计8字节(为4字节(32位)的整数倍)需要访存2次就能取出数据(执行阶段),而B结构体中,默认按照有效对齐值对齐,则char类型所占空间扩展为4字节,int占4字节,short扩展为4字节,共占12个字节。

设想一下如果没有字段对齐,当要取B结构中的第二个int时,将会先取出其前3个字节然后第二次访存取出其最后一个字节,显然效率太低(举一个不太恰当的例子,好比用一个大夹子去夹取一些货物,如果每次夹取前都要调整夹子的宽度势必会耽误时间,也可以类比一下计算机网络中数据包的封装,比如TCP/IP协议中的数据包头都是对齐封装的,也是为了便于读取迅速以提高效率)

四、总结

以上就是字段对齐的过程和意义,需要注意的是有些比较严格的机器会有一些字段对齐相关的错误隐患,比如部分机器要求首地址均从偶数开始(因为数据所占字节数均为2的指数幂),如果从奇数边界去访问数据变量就可能出现报错。

人类对CPU资源蛮横无理的榨取就如同当年资本主义剥削无产阶级每一分劳动剩余价值一样残酷,但是这种“残酷”却将使人类文明不断向前迈进。

参考资料来源:

http://blog.csdn.net/21aspnet/article/details/6729724

http://blog.163.com/[email protected]/blog/static/109968875201232012758232/

https://software.intel.com/zh-cn/articles/book-Processor-Architecture_CPU_work_process

http://home.51.com/fogball/diary/item/10055783.html

时间: 2024-10-27 08:32:47

关于字节对齐的理解的相关文章

字节对齐

今天我们总结在C++和C语言中让我们头疼的字节对齐问题: 一.首先来看什么是字节对其? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任 何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐. 二: 那么问题就来了为什么要字节对其?以及字节对其的作用? 各个硬件平台对存储空间的处理上有很大的不同.一些平台对某些特定类型的数据只能从某些特定地址开始存

C语言:内存字节对齐详解[转载]

一.什么是对齐,以及为什么要对齐: 1. 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐. 2. 对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同.一些平台对某些特定类型的数据只能从某些特定地址开始存取.其他平台可能没有这种情况, 但是最常见的是如果不按照适合其平台的要求对数据存放进行对齐

字节对齐问题

文章最后本人做了一幅图,一看就明白了,这个问题网上讲的不少,但是都没有把问题说透. 32位机器上各种数据类型的长度如下:char:1(有符号无符号同) short:2(有符号无符号同) int:4(有符号无符号同) long:4(有符号无符号同) float:4 double:8 一.概念    对齐跟数据在内存中的位置有关.如果一个变量的内存地址正好位于它长度的整数倍,他就被称做自然对齐.比如在32位cpu下,假设一个整型变量的地址为0x00000004,那它就是自然对齐的.   二.为什么要

C语言字节对齐 __align(),__attribute((aligned (n))),#pragma pack(n)

转载地址 : http://blog.csdn.net/21aspnet/article/details/6729724 一.概念    对齐跟数据在内存中的位置有关.如果一个变量的内存地址正好位于它长度的整数倍,他就被称做自然对齐.比如在32位cpu下,假设一个整型变量的地址为0x00000004,那它就是自然对齐的.   二.为什么要字节对齐   需要字节对齐的根本原因在于CPU访问数据的效率问题.假设上面整型变量的地址不是自然对齐,比如为0x00000002,则CPU如果取它的值的话需要访

C/C++基础笔试题1.0(字节对齐)

传说中博文标题带有笔试.面试等点击率都会很高呢?我也试试! 众生皆是码农命,我们这种即将战秋招的渣渣,既没有超凡的能力,也没有流弊的项目,怎么破? 唯独苦苦怒刷基础,笔试题,面试题,因为以前常常刷OJ,所以很多面试题的编程题倒是可以解,但是笔试题或者基础题我就不记得了,唯独慢慢回想. 况且,写这种面试题,谁能写得赢JULY神. 今天首先讲得是字节对齐. 注意:我是一个渣,所以我只能按自己的理解来说了(要不然怎么会这么惨呢?).如果你想看大神的解释,请看这里 来看个题目 #include <ios

C语言结构体的字节对齐原则

转载:http://blog.csdn.net/shenbin1430/article/details/4292463 为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐. 对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同.一些平台对某些特定类型的数据只能从某些特定地址

C++字节对齐问题

关于C++字节对齐问题 关于C/C++的字节对齐 这两天写解析SWF文件的程序,在结构体指针和从文件里读出来的进行转换的时候遇到一些问题,就是有一个struct A,比如: struct A { char flag; int length; int id; .... }; 然后一个飘逸的 struct A *a = (struct A*)buffer;   // 世界一下清静咯 可惜在输出a中的成员的时候却发现老是不对,百思不得起解.今晚一想,可能是因为C++的字节对齐问题,所以直接就百度了一些

字节对齐2

字节顺序是指占内存多于一个字节类型的数据在内存中的存放顺序,通常有小端.大端两种字节顺序.小端字节指低字节数据存放在内存低地址处,高字节数据存放在内存的高地址处:大端字节序是高字节数据存放在低地址处,低字节数据存放在高地址处.基于X86平台的PC机是小端字节序的,而有的嵌入式平台则是大端字节序的.因而对int.uint16.uint32等多于1字节类型的数据,在这些嵌入式平台上应该变换其存储顺序.通常我们认为,在网络中传输的字节的顺序即网络字节序为标准顺序,考虑到与协议的一致以及与同类其他平台产

字节对齐1

一.快速理解1.什么是字节对齐?    在C语言中,结构是一种复合数据类型,其构成元素既可以是基本数据类型(如int.long.float等)的变量,也可以是一些复合数据类型(如数组.结构.联合等)的数据单元.在结构中,编译器为结构中的每个成员按其自然边界(alignment)分配空间.各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同.    为了使CPU能够对变量进行快速的访问,变量的起始地址应该具有某些特性,即所谓的“对齐”,比如4字节的int型,其起始地址