最近和同事谈到了ARM平台下数据总线宽度及对齐方式对程序效率的影响问题,在定义结构数据类型时,为了提高系统效率,要注意字长对齐原则。正好有点感触和大家一起谈谈。
这里主要给大家解释下所谓的对齐到底是什么?怎么对齐?为什么会对齐或者说对齐带来什么样的效率差异?
1.先看下面的例子:
#include
#pragma pack(4)
struct A
{
char a;
int b;
};
#pragma pack()
#pragma pack(1)
struct B
{
char a;
int b;
};
#pragma pack()
int main()
{
A a;
cout<
B b;
cout<
}
默认的vc++我记得是4字节对齐ADS下是一字节对齐,因为是c/c++社区大家对PC比较熟悉 我就谈PC下的对齐。
PC下设计放的太长时间的有错误就别客气直接说,大家可以看到在ms的vc下按4字节对齐和1字节对齐的结果是截然不同的分别为8和5为什么会有这样的结果呢?这就是x86上字节对齐的作用。
为了加快程序执行的速度,一些体系结构以对齐的方式设计,通常以字长作为对齐边界。对于一些结构体变量,整个结构要对齐在内部成员变量最大的对齐边界,如A,整个结构以4为对齐边界,所以sizeof(a)为8,而不是5。
如果是原始我们概念下的的A中的成员将会一个挨一个存储,应该只有char+int只有5个字节。这个差异就是由于对齐导致的。,然我们可以看到A的对齐要比B浪费3个字节的存储空间。
那为什么还要采取对齐呢?
那是因为体系结构的对齐和不对齐,是在时间和空间上的一个权衡。
字节对齐节省了时间。应该是设计者考虑用空间换取时间。
为什么说对齐会提高效率呢节省时间?我想大家要理解的重点之重点就在这里了。
在我们常用的PC下总线宽度是32位
1.如果是总线宽度对齐的话
那么所有读写操作都是获取一个<=32位数据可以一次保证在数据总线传输完毕
没有任何的额外消耗
|1|2|3|4|5|6|7|8|
从1开始这里是a的起始位置,5起始为b的位置 访问的时候
如果访问a一次在总线传输8位其他24位无效的
访问b时则一次在总线上传输32完成
读写均是一次完整
插叙一下 读操作先要将读地址放到地址总线上然后下个时钟周期再从外部
存储器接口上读回数据通过数据总线返回需要两个周期
而写操作一次将地址及数据写入相应总线就完成了
读操作要比写操作慢一半
2.我们看访问数据时如果不对齐地址的情况
|1|2|3|4|5|6|7|8|
此时a的地址没变还在1而因为是不对齐则b的位置就在2处
这时访问就带来效率上问题 访问a时没问题还是读会一个字节
但是2处地址因为不是总线宽度对齐一般的CPU在此地址操作将产生error
如sparc,MIPS。它们在硬件的设计上就强制性的要求对齐。在不对齐的地址上肯定发生错误
但是x86是支持非对齐访问的
它通过多次访问来拼接得到的结果,具体做法就是从1地址处先读回后三字节234 暂存起来
然后再由5地址处读回一个字节5 与234进行拼接组成一个完整的int也就是b返回
大家看看如此的操作带来的消耗多了不止三倍很明显在字长对齐时效率要高许多
淡然这种效率仅仅是访问多字节带来的 如果还是进行的byte操作那效率差不了多少
目前的开发普遍比较重视性能,所以对齐的问题,有2种不同的处理方法:
1) 有一种使用空间换时间做法是显式的插入reserved成员:
struct A{
char a;
char reserved1[3]; //使用空间换时间
int b;
}a;
2) 随便怎么写,一切交给编译器自动对齐。
还有一种将逻辑相关的数据放在一起定义
代码中关于对齐的隐患,很多是隐式的。比如在强制类型转换的时候。下面举个例子:
unsigned int i = 0x12345678;
unsigned char *p=NULL;
unsigned short *p1=NULL;
p=&i;
*p=0x00;
p1=(unsigned short *)(p+1);
*p1=0x0000;
最后两句代码,从奇数边界去访问unsignedshort型变量,显然不符合对齐的规定。
在x86上,类似的操作只会影响效率,但是在MIPS或者sparc上,可能就是一个error
上一篇:基于ARM处理器的高效异常处理解决方案
下一篇:解析J-Link、J-Trace、Open JTAG原理以及其区别
推荐阅读最新更新时间:2024-11-08 18:01
设计资源 培训 开发板 精华推荐
- USB-5V&3.3V-BL1117-33CX
- AD8627ARZ-REEL精密放大器用于8极Sallen-Key低通滤波器的典型应用电路
- MC78M12ACDTRKG 12V 升压稳压器的典型应用
- 【彩色丝印】基于CH334R的USB2.0 HUB
- EVAL-INAMP-82RMZ,用于评估仪表放大器 AD8220 的评估板
- EB7760,用于 SPT7760、8 位、1 GSPS 示波器模数转换器的评估板
- NUC-PowerCube 四足NUC电源模块
- 迷你二级降压模块-兼容TO-252-2脚位
- 基于 ADXL362 的超低功耗、3 轴、运动激活开关
- DC2425A-B,使用 LTC2310IMSE-16 16 位、2Msps 真差分输入串行 SAR ADC 的演示板
- AMD推出第二代Versal Premium系列产品:首款PCIe 6.0和CXL 3.1的SoC FPGA
- 红帽宣布达成收购Neural Magic的最终协议
- 5G网速比4G快但感知差!邬贺铨:6G标准制定应重视用户需求
- SEMI报告:2024年第三季度全球硅晶圆出货量增长6%
- OpenAI呼吁建立“北美人工智能联盟” 好与中国竞争
- 传OpenAI即将推出新款智能体 能为用户自动执行任务
- 尼得科智动率先推出两轮车用电动离合器ECU
- ASML在2024 年投资者日会议上就市场机遇提供最新看法
- AMD将裁员4%,以在人工智能芯片领域争取更强的市场地位
- Arm:以高效计算平台为核心,内外协力共筑可持续未来