内存对齐的规则以及作用

  首先由一个程序引入话题:

 1 //环境:vc6 + windows sp2
 2 //程序1
 3 #include <iostream>
 4 
 5 using namespace std;
 6 
 7 struct st1 
 8 {
 9     char a ;
10     int  b ;
11     short c ;
12 };
13 
14 struct st2
15 {
16     short c ;
17     char  a ;
18     int   b ;
19 };
20 
21 int main()
22 {
23     cout<<"sizeof(st1) is "<<sizeof(st1)<<endl;
24     cout<<"sizeof(st2) is "<<sizeof(st2)<<endl;
25     return 0 ;
26 }
27 

程序的输出结果为:

 sizeof(st1) is 12

        sizeof(st2) is 8 

 

问题出来了,这两个一样的结构体,为什么sizeof的时候大小不一样呢?

本文的主要目的就是解释明白这一问题。

 

内存对齐,正是因为内存对齐的影响,导致结果不同。

对于大多数的程序员来说,内存对齐基本上是透明的,这是编译器该干的活,编译器为程序中的每个数据单元安排在合适的位置上,从而导致了相同的变量,不同声明顺序的结构体大小的不同。

 

       那么编译器为什么要进行内存对齐呢?程序1中结构体按常理来理解sizeof(st1)和sizeof(st2)结果都应该是7,4(int) + 2(short) + 1(char) = 7 。经过内存对齐后,结构体的空间反而增大了。

在解释内存对齐的作用前,先来看下内存对齐的规则:

1、  对于结构的各个成员,第一个成员位于偏移为0的位置,以后每个数据成员的偏移量必须是min(#pragma pack()指定的数,这个数据成员的自身长度) 的倍数。

2、  在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。

 

#pragma pack(n) 表示设置为n字节对齐。 VC6默认8字节对齐

以程序1为例解释对齐的规则 :

St1 :char占一个字节,起始偏移为0 ,int 占4个字节,min(#pragma pack()指定的数,这个数据成员的自身长度) = 4(VC6默认8字节对齐),所以int按4字节对齐,起始偏移必须为4的倍数,所以起始偏移为4,在char后编译器会添加3个字节的额外字节,不存放任意数据。short占2个字节,按2字节对齐,起始偏移为8,正好是2的倍数,无须添加额外字节。到此规则1的数据成员对齐结束,此时的内存状态为:

oxxx|oooo|oo


0123 4567 89 (地址)

(x表示额外添加的字节)

共占10个字节。还要继续进行结构本身的对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行,st1结构中最大数据成员长度为int,占4字节,而默认的#pragma pack 指定的值为8,所以结果本身按照4字节对齐,结构总大小必须为4的倍数,需添加2个额外字节使结构的总大小为12 。此时的内存状态为:

oxxx|oooo|ooxx

0123 4567 89ab  (地址)

到此内存对齐结束。St1占用了12个字节而非7个字节。

 

St2 的对齐方法和st1相同,读者可自己完成。

 

内存对齐的主要作用是:

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

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

 

图一:

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

 

图二:


CPU把内存当成是一块一块的,块的大小可以是2,4,8,16字节大小,因此CPU在读取内存时是一块一块进行读取的。块大小成为memory access granularity(粒度) 本人把它翻译为“内存读取粒度” 。

 

假设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遇到未对齐边界就直接罢工了。

 

图片来自:Data alignment: Straighten up and fly right 

如大家对内存对齐对性能的具体影响情况,可以参考上文。

//

 转载:http://www.cppblog.com/snailcong/archive/2009/03/16/76705.html


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/492377.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

中国AI创新者论坛成功举办!这里有一份AI教育和医疗的落地秘籍

来源&#xff1a;THU数据派3月21日&#xff0c;由网易新闻、网易有道、清华数据院共同举办的以“创新&#xff0c;无界”为主题的“中国AI创新者论坛”在清华大学罗姆楼三层报告厅成功举办。律回岁晚冰霜少&#xff0c;春到人间草木知&#xff0c;初春的北京&#xff0c;顶级人…

windows下jenkins slave 搭建

一 创建新的Slave 注意Jenkins中slave称为note。 所以下面文章中的slave和node指的是一回事。 1&#xff09;在Manage Jenkins-->Manage Nodes -->New Node下&#xff1a;输入Node Name&#xff0c;且选择Dumb Slave作为Slave的类型&#xff0c;然后OK。 2&#xff09;在…

MEMS:万物智联技术关键

来源&#xff1a;Research摘要&#xff1a;MEMS技术在汽车电子、生物医疗、智慧家庭、工业物联网、消费电子等领域都有着广阔的市场前景。随着万物互联时代的加快到来&#xff0c;MEMS传感器将迎来新的浪潮。一、MEMS 是什么1、MEMS 定义MEMS&#xff08;Microelectromechanica…

2019年25大人工智能趋势!一文看到未来

来源&#xff1a;智东西摘要&#xff1a;2019年25个AI趋势。人工智能的下一步是什么&#xff1f;上周&#xff0c;知名机构CBinsights的分析师分析各个行业&#xff0c;得到了2019年最值得关注的25个人工智能趋势。虽然人工智能正在各个行业蔓延&#xff0c;经常成为头条新闻&a…

重磅!首次发现人类大脑海马体在短时间尺度上对时间信息敏感

来源&#xff1a;brainnews编译&#xff1a;南樛木早期对啮齿动物海马体的研究提供了情景记忆中海马体表达时间信息的一般神经机制证据。对记忆编码的方式涉及到许多信息&#xff0c;科学家们已经研究了其中大部分是如何工作的。但是有一个维度仍未得到解决&#xff1a;时间。最…

2015新款 MacBook 用心的测评与试用. 最轻薄的Mac上市

2015新款 MacBook 不一样的测评与试用. 最轻薄的Mac上市了. 直击现场 《HTML开发MacOSApp教程》 http://pan.baidu.com/s/1jG1Q58M 2015年的春季的苹果特别媒体发布会上, 苹果发布了超轻薄的 MacBook 产品. 或许当你阅读本文的时候已经看过不少跑分, 性能测试文章, 为了不让…

数字图像处理——图像的几何变换

这次学习图像的几何变换&#xff0c;主要有以下内容&#xff1a;图像的平移变换图像的镜像变换图像的转置变换图像的旋转变换图像的缩放1、图像的平移变换在进行书写matlab代码之前&#xff0c;先来了解一下图像平移的理论基础。设图像的高度为H&#xff0c;宽度为W&#xff0c…

万字长文解读运营商搏击5G:一场比拼财力的三国杀

来源&#xff1a;财经无忌摘要&#xff1a;5G时代已经来临&#xff0c;5G走向商用的步伐也在逐渐加快。近日&#xff0c;腾讯科技联合优质科技媒体推出“5G局中局”系列文章&#xff0c;为你解读5G在通讯、物联网、车联网、工业联网、边缘计算、云服务等各行业的应用&#xff0…

MVP

MVP是一种广泛使用的UI架构模式&#xff0c;适用于基于事件驱动的应用框架。 能够与 Model直接进行交互的仅限于 Presenter, View 只能通过 Presenter 间拉地调用 Model。 MVP分PV&#xff08;Passive View) 和 &#xff08;Supervising Controller)两种模式 SC(Supervising Co…

OpenCV——图像显示与写入

1、图像显示与写入的代码如下&#xff1a; #include<opencv2/core/core.hpp> #include<opencv2/highgui/highgui.hpp>using namespace cv; using namespace std; //opencv中图像显示与写入 int main() {Mat myMat imread("小狗1.jpg", -1);if (myMat.em…

工业3D打印:一场仍处在初级阶段的技术革命

来源&#xff1a;资本实验室摘要&#xff1a;曾记否&#xff0c;几年前当我们在实体店看到3D打印机打印出的一个个小玩意时&#xff0c;那种油然而生的新鲜与神奇感&#xff1f;然而&#xff0c;短短几年&#xff0c;面对这种新事物&#xff0c;我们已经见怪不怪。此外&#xf…

OpenCV——读取视频文件并写入文件

1、代码如下&#xff1a; #include<opencv2/opencv.hpp> using namespace cv;//-----------------------------------【main()函数】-------------------------------------------- // 描述&#xff1a;控制台应用程序的入口函数&#xff0c;我们…

人工智能的现状与未来(附PPT)

来源&#xff1a;网经科技摘要&#xff1a;人工智能引领新的工业革命&#xff0c;需要正确理解其技术核心、学科定位、架构演进&#xff0c;当前深度学习和知识图谱成其左膀右臂&#xff0c;象征人类智谋的智能博弈在围棋后的下一个高地在哪里&#xff1f;走向人机融合的未来&a…

【最新】三位深度学习创始人共同获得了2019年公布的图灵奖

来源&#xff1a;biendata数据实战派2019年3月27日 ——ACM宣布&#xff0c;深度学习的三位创造者Yoshua Bengio, Yann LeCun, 以及Geoffrey Hinton获得了2019年的图灵奖。今天&#xff0c;深度学习已经成为了人工智能技术领域最重要的技术之一。在最近数年中&#xff0c;计算机…

Throwable 结构图

从这个图中就可以看出运行时异常是数组越界、空指针、类转换错误之类的异常&#xff0c;解决方法是修改代码而其他异常&#xff0c;也就是已检查异常&#xff0c;则是需要抛出或者捕捉转载于:https://www.cnblogs.com/dolphin007/p/4446105.html

无人驾驶产业发展现状及影响

来源&#xff1a;《中国国情国力》杂志摘要&#xff1a;无人驾驶产业将是我国对美欧日等传统汽车大国实现变道超车的重要领域。我国无人驾驶产业需求巨大、规模快速增长&#xff0c;但是人才缺口和尚不完善的法律仍是制约产业发展的障碍。无人驾驶产业改变了就业结构&#xff0…

Java中9种IO的读取方式

数据的读写&#xff0c;按照数据类型可以分为两种&#xff1a;字符流和字节流&#xff08;二者区别&#xff1f;&#xff09;。所以数据读取方式按照数据类型也可以分为两类&#xff1a;字节流的读取和字符流的读取。 一、字节流读取操作&#xff1a;| ||-----1、FileInputStre…

推翻《Nature》:生命不息,神经发生不止...

摘要&#xff1a;热播剧《都挺好》里的巨婴苏大强最后也患了阿尔兹海默症来源&#xff1a;中国生物技术网上图显示了68岁时死亡的男性海马齿状回的组织。他在死亡时有一个健康的大脑。在图片中&#xff0c;新鲜的脑细胞呈红色&#xff0c;成熟的脑细胞呈蓝色。图片来源&#xf…

OpenCV—基本矩阵操作与示例

OpenCV的基本矩阵操作与示例OpenCV中的矩阵操作非常重要&#xff0c;本文总结了矩阵的创建、初始化以及基本矩阵操作&#xff0c;给出了示例代码&#xff0c;主要内容包括&#xff1a;创建与初始化矩阵加减法矩阵乘法矩阵转置矩阵求逆矩阵非零元素个数矩阵均值与标准差矩阵全局…

人工智能的三大教父,谱写了一段关于勇气的寓言

来源&#xff1a;原理上世纪80年代末&#xff0c;还在加拿大攻读硕的尤舒亚本吉奥&#xff08;Yoshua Bengio&#xff09;被一个当时并不怎么流行的想法迷住了。那时&#xff0c;有少数从事人工智能研究的计算机科学家试图研发这样一种软件&#xff0c;这种软件可以大致模仿神经…