小心内存对齐

什么是内存对齐?

CPU在读取内存地址的时候,一定按照一定的偏移量去读取,不知道你发现了没有,我们没有看到一个变量的大小是 3 个字节的,都是 1 个字节,2个字节,4个字节,8个字节,16个字节,32个字节。

为什么会这样呢?因为CPU设计的时候,没有一个 3 、5、7、9这样的模子,因为设计这样的模子非常费劲。

为什么要内存对齐?

之前网上有一个一个例子,如果一个变量int 的起始地址偏移是3,那么CPU要取这个地址上的数据,需要取两次,为什么呢?

640?wx_fmt=png假设一个变量 在内存的位置 从地址 1开始存放数据,因为这个是int类型,它占用4个字节的内存空间。

我们用一个int 的模子「int模子是4个字节」来卡这个数据,实际上是这样操作的,第一次卡模子,只能从0开始640?wx_fmt=png第二次卡模子,再从3位置开始640?wx_fmt=png从图片上可以明显看出来,我们需要CPU卡两次模子,才取到在内存里面的 int 变量

如果int 是按照内存对齐的方式存放的呢?

640?wx_fmt=png很明显,我们只需要卡一次模子就可以取到数据了。

内存对齐引发的问题

前两天,我们群上有一个同学,发了一份这样的代码出来,代码写得还是有一点风骚的,这位同学说,这个代码在A单片机上运行得非常OK,也已经出货了几万台了,但是这个代码移植到单片机B上后,就挂了,大家帮忙看看这个代码有什么问题?

uint8_t buf[16];	
uint8_t i;	
uint16_t data;	for (i=0; i<16; i+=2)	
{	data = *((uint16_t *)&buf[i]);	
}

问题的原因

经过一段激烈的讨论,后面发现是内存对齐的问题,一个群友画了一个图,写的很清楚了,因为char 是对单字节对齐的,所以没有问题,但是uint16_t 默认是对双字对齐的,所以如果初始地址是奇数的话,最后就出现内存越界了。640?wx_fmt=png

一个图片说明不同数据类型的内存对齐

640?wx_fmt=png

使用#pragma pack()限定内存对齐

我们可以使用宏 #pragma pack() 来指定内存对齐的方式,这里我就不展开说明了,如果说明太多了,后面用一个文章来单独说明,喜欢了解的同学可以百度看看,内容还是比较多的。

内存对齐可以提升CPU效率

我们知道单字节对齐的效率应该是最低的,我给两个代码给大家看看,比较一下,单字节和双字节内存对齐对CPU效率的影响。

单字节对齐函数

void Munge8( void ∗data, uint32_t size ) {	uint8_t ∗data8 = (uint8_t∗) data;	uint8_t ∗data8End = data8 + size;	while( data8 != data8End ) {	∗data8++ = ‑∗data8;	}	
}

双字节对齐函数

void Munge16( void ∗data, uint32_t size ) {	uint16_t ∗data16 = (uint16_t∗) data;	uint16_t ∗data16End = data16 + (size >> 1); /∗ Divide size by 2. ∗/	uint8_t ∗data8 = (uint8_t∗) data16End;	uint8_t ∗data8End = data8 + (size & 0x00000001); /∗ Strip upper 31 bits. ∗/	while( data16 != data16End ) {	∗data16++ = ‑∗data16;	}	while( data8 != data8End ) {	∗data8++ = ‑∗data8;	}	
}

这个代码大家可以直接拿去执行试试,最终的结果如下面的图片

640?wx_fmt=png

果修改成 4 字节对齐的话,结果将会更加有意思

四字对齐函数

void Munge32( void ∗data, uint32_t size ) {	uint32_t ∗data32 = (uint32_t∗) data;	uint32_t ∗data32End = data32 + (size >> 2); /∗ Divide size by 4. ∗/	uint8_t ∗data8 = (uint8_t∗) data32End;	uint8_t ∗data8End = data8 + (size & 0x00000003); /∗ Strip upper 30 bits. ∗/	while( data32 != data32End ) {	∗data32++ = ‑∗data32;	}	while( data8 != data8End ) {	∗data8++ = ‑∗data8;	}	
}

640?wx_fmt=png他们的效率主要体现在字节不对齐的时候,如果字节默认已经是对齐的时候,那效果更是快得飞起。

参考

https://developer.ibm.com/articles/pa-dalign/

留个问题

上面有问题的代码如何修改?

回答正确的前三名,我发心意红包

640?wx_fmt=jpeg

640?wx_fmt=jpeg

扫码或长按关注

回复「 加群 」进入技术群聊

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

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

相关文章

mysql为什么不驼峰_为什么不用驼峰命名创建表名和字段?

其实&#xff0c;这是一种规范&#xff0c;而不是一种规则。所以你使用驼峰来命名也是可以的&#xff0c;但是我们要避免用驼峰来命名。不只是数据库&#xff0c;就是平常的程序也是&#xff0c;因为&#xff1a;MYSQL 5.7 FEATURES. THIS MANUAL DESCRIBES FEATURES THAT ARE …

JavaScript获取select下拉框中的第一个值

JavaScript获取select下拉框中的第一个值 1、说明 获取select下拉框中的第一个值 2、实现源代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns&quo…

好用的平板电脑_支架里的变形金刚让手机、电脑、平板更好用!6种角度,1秒切换...

六 月 惊 喜戳 这 里嗨&#xff0c;我是专注研究数码3C产品的小嘻~对于当代人来说&#xff0c;办公、学习、娱乐离不开三件宝&#xff1a;手机、平板、电脑。手机不离手&#xff0c;沟通工作、看剧、刷抖音&#xff0c;没留神几个小时就过去了&#xff0c;放下手机的时候就觉得…

推荐一位AI技术人

今天推荐认识的一个朋友&#xff0c;推荐的原因很简单&#xff0c;因为他非常喜欢篮球&#xff0c;正统校队篮球队员&#xff0c;这个AI相关的公众号一直是他个人运营&#xff0c;写了非常多的文章&#xff0c;如果大家有在学习AI相关的知识&#xff0c;强烈推荐关注。AI蜗牛车…

python从入门到大神系列手机_python从入门到大神---2、和Python编程相遇的日子

python从入门到大神---2、和Python编程相遇的日子一、总结一句话总结&#xff1a;python2和python3是很不同的&#xff0c;连语法都不同&#xff0c;比如 print 函数打印结果1、python中pip安装的包放在哪&#xff1f;lib\site-packages\包名\&#xff1a;包总是被安装在python…

flask 安装

flask官网 &#xff1a; http://docs.jinkan.org/docs/flask/installation.html &#xff08;基本上就是按照官网思路一点一点来的&#xff09; 1&#xff0c;安装easy_install: wget -q http://peak.telecommunity.com/dist/ez_setup.pypython ez_setup.py 2&#xff0c;安装…

如何 给给软件开发 添加 代理_敏捷开发是如何被跑偏的

今天聊聊敏捷软件过程。先说结论&#xff1a;据我观察&#xff0c;至少有60%的团队误用了敏捷软件过程&#xff0c;或者说至少60%的团队在进行伪敏捷开发。与大家通常的认知是相反的&#xff0c;敏捷过程并不是一个非常容易实践或者实施的过程规范。通常来讲&#xff0c;没有天…

在实时操作系统里随便写代码都能硬实时吗?

这是转发宋老师写的文章&#xff0c;我也是刚知道&#xff0c;宋老师跟我一样也是养娃的人了&#xff0c;国庆期间&#xff0c;看看文章&#xff0c;看看升升国旗。很久没有写技术文章了&#xff0c;做码农难&#xff0c;做养娃的码农更难&#xff0c;趁着娃看动画片的机会&…

《C程序设计语言》-第2章-习题

本人写的代码可能与标准答案有出入&#xff0c;但运行是没问题的&#xff0c;欢迎大家相互参考学习。 《C程序设计语言习题》2-1&#xff1a; 编写一个程序以确定分别由signed及unsigned限定的char、short、int及long类型变量的取值范围。采用打印标准头文件中的相应值以及直接…

python 数据分析 实际案例_python实战案例:超市营业额数据分析

实战是学习的最好途径&#xff0c;效率最高&#xff0c;本文不是很长&#xff0c;通过小小的练习&#xff0c;让大家综合运用基础知识&#xff0c;加深印象巩固记忆。一、读入数据&#xff0c;了解数据本数据随机生成的假数据&#xff0c;读者可以自己造&#xff0c;也可以通过…

台达n2系列变频器_台达变频器C2000系列在Profibus网络中的应用

基本介绍现场总线就是顺应信息技术的发展趋势和工业控制系统的分散化、网络化、智能化要求而发展起来的新技术&#xff0c;它的出现和发展已经成为全球工业自动化技术的热点之一&#xff0c;受到全世界和工业界的普遍重视。现场总线(Fieldbus)技术是实现现场级控制设备数字化通…

python和c语言混合编程-python和C语言混编的几种方式

版权申明&#xff1a;本文为博主窗户(Colin Cai)原创&#xff0c;欢迎转帖。如要转贴&#xff0c;必须注明原文网址 http://www.cnblogs.com/Colin-Cai/p/7594551.html 作者&#xff1a;窗户 QQ&#xff1a;6679072 E-mail&#xff1a;6679072qq.com Python这些年风头一直很盛&…

CentOS 6.8 虚拟机安装详解

第一步&#xff1a;安装 VMware 官方网站&#xff1a;www.vmware.com 下载百度云链接&#xff1a;http://pan.baidu.com/s/1bphDOWv 密码&#xff1a;0zix VMware 是一个虚拟 PC 的软件&#xff0c;可以在现有的操作系统上虚拟出一个新的硬件环境&#xff0c;相当于模拟出一台新…

unittest里discover用法_unittest框架核心要素及应用

1. unittest核心要素unittest介绍测试框架&#xff0c;不仅仅用于单元测试python自动的测试包用法和django.test.TestCase类似1.1【知道】unittest介绍和核心要素1.2【掌握】unittest核心要素的使用""" 1. 测试用例 2. 容器&#xff0c;容器添加测试用例 3. 运行…

void函数调用时显示不允许使用不完整的_4位数码管显示模块驱动

TM1637四位数码管模块是一个带时钟点的4位共阳数码管(0.36英寸)的显示模块&#xff0c;驱动芯片为TM1637&#xff0c;驱动方式为IIC&#xff0c;因此只需2根信号线即可使单片机控制4位8段数码管(数码管8级亮度可调)。模块特点如下&#xff1a;显示器件为4位共阳数码管数码管8级…

在线就能用的Linux我给你找好了

今天的天气真的是超级爽&#xff0c;秋日的凉风吹在脸上真的太美了&#xff0c;好不容易的假期&#xff0c;希望大家都玩得开心&#xff0c;今天分享一篇文章&#xff0c;是守望兄的&#xff0c;总结了几个在线的Linux&#xff0c;喜欢的同学&#xff0c;可以保存下来&#xff…

【BZOJ3640】JC的小苹果 概率DP+高斯消元

【BZOJ3640】JC的小苹果 Description 让我们继续JC和DZY的故事。 “你是我的小丫小苹果&#xff0c;怎么爱你都不嫌多&#xff01;” “点亮我生命的火&#xff0c;火火火火火&#xff01;” 话说JC历经艰辛来到了城市B&#xff0c;但是由于他的疏忽DZY偷走了他的小苹果&#x…

mysql访问类型最好的_【干货满满】最全的MySQL性能指南(一):选择最佳的数据类型...

对于 MySQL 数据库来说&#xff0c;好的逻辑表和物理表的规划至关重要&#xff0c;我们需要根据查询语句来针对性地设计 Schema &#xff0c;没有万能好用的 Schema。一个 denormalized 的 schema 可以在某些场景下加速语句查询&#xff0c;但是放在其他应用场景下就会适得其反…

测试两个主机之间的连通性_借助网络测试神器极速解决网络故障

时下&#xff0c;网络使用越来越频繁&#xff0c;随之遇到网络故障的情况也多起来&#xff0c;那么诊断网络故障就成了必不可少的一环&#xff0c;投诉和求助是一种基本的方法&#xff0c;但有时太过缓慢&#xff0c;有些时候自己可以快速搞定&#xff0c;检查到故障原因所在&a…

随想,对嵌入式职场建议

guoqingjie已经过去两天了&#xff0c;因为楠哥生病&#xff0c;我们搁浅在了深圳&#xff0c;不过相比在路上的奔波&#xff0c;待在家里感觉惬意不少&#xff0c;不用在路上各种操心&#xff0c;之前上班感冒&#xff0c;身体处在亚健康状态&#xff0c;睡了两天身体也恢复一…