共2条
1/1 1 跳转至页
32 把变量统一为32位是否可以提高性能?
问
现在大家都是8位,16位,32位变量混用。那么把变量统一为32位是否可以提高性能?
答 1:
没人回么? 顶一下。
答 2:
没人知道么? 因为看周立功的书上说4版以前只支持字节和双字,5版以后才支持字(16位)。而且单步调试时好像16位是靠移位获得的。
答 3:
再顶一下! 变量混用好像还有对齐问题。就没人讨论一下吗?这个问题还是很普遍的。
答 4:
是的,但是现在我好象还没发现什么规律。大家在实际使用的情况呢?
答 5:
周工的开发经验很丰富吧? 说一下您的看法?
答 6:
re: 个人见解: 一般函数内的动态局部变量使用32位效率会高一点,因为这些变量会使用寄存器存储,32位的话就不需要“与”“或”操作。
如果变量是保存在外部RAM(8位或16位接口),那就没有必要全部使用32位了。
答 7: 大家还有别的意见吗? 一起讨论讨论吧。 答 8: 期待正在做一个项目,现在对RAM的使用充满了疑惑。期待大家讨论。 答 9: 从8位机上过来的,所以。一直大量使用8位方式。
当然,公司产品与外设(I2C、SPI....)关系非常密切,所以,理所当然使用8位。
多数情况下,没有对性能锱铢必较。
答 10: 以前看过某书上说,变量字长与芯片字长一样时,效率最高 答 11: 我之愚见对于32位的来说,最好是统一.即使不统一,也不要混合声明,要按照一定顺序来才好. 答 12: 一些看法ARM有点特殊,他不像x86架构保留一些历史残留,在x86中例如32bit的寄存器EAX(32bit)可分解出一个AX(16bit),还有AX何以分解为AH和AL两个8bit寄存器,几乎每种寄存器都可以作为操作数独立操作,但是现行32bit编译器(例如VC)似乎都愿意把他们作为32bit变量运算,这样就会使得存取数据时候需要额外的“与或”“移位”操作修正变量从而会降低了一些效率;
而对于本身就是8bit宽度的51单片机来说,最快的处理当然是8bit变量,个人认为随着变量宽度递增其代码时空效率也几乎线性递减的。
在过去很长一段时间受一些win32编译器影响也认为ARM使用非机器字长的变量进行运算会明显降低代码的时空效率,但是后来发现这个差距变得非常小,现在的ARM出生没有什么历史残留,基本寄存器就是32bit的,因此绝大多数运算不管变量宽度都是用同一套指令操作,效率没有明显的差别,而且在数据存取的指令集中str/ldr都是允许带b或者h等后缀使得8bit或者16bit数据存取都可以使用一条指令完成;(以上针对片内flash/RAM,ADS编译器提出)
就ADS而言,其实真正的代码时空效率问题会由于改变了默认对齐引起的,常见的位域、压缩的结构(人为改变结构成员按机器字长对齐的规则)都是牺牲性能换取编程操作方便或者RAM空间的,这时候访问这些数据成员就需要额外的时空代价了。
就自己的观点看来:
1,如没有特殊原因尽可能使用与机器字长一致的变量,特别是临时变量;
2,若不是为了满足硬件寄存器分布映射、固定的软件协议等特殊需要(包括资源紧张)时不要人为改变数据存储对齐宽度;
3,对于ARM编程不要片面追求效率; 答 13: 说的也是,外围大多是8位的器件,包括串行的,并行的 UART IIC SPI的缓冲区,我都用8位的 答 14: 下面的文字引自ARM中国的一篇文档。一般情况下人们总是设法使用short 或char 来定义变量以节省存储器空间;但是,当一个函数的局部变量数目有限的情况下,编译器会把局部变量分配给内部寄存器,每个变量占用一个寄存器。这样,使用short 和char 型变量不但起不到节省空间的作用,还会带来其他的副作用,
请看图2。假定a1 是任意可能的寄存器,存储函数的局部变量。同样完成加一的操作,32 位的int 型变量最快,只用一条加法指令。而8 位和16 位变量,完成加法操作后,还需要在32 位的寄存器中进行符号扩展,其中带符号的变量,要用逻辑左移(LSL)接算术右移(ASR)两条指令才能完成符号扩展;无符号的变量,要使用一条逻辑与(AND)指令对符号位进行清零。所以,使用32 位的int 或unsigned int 局部变量最有效率。某些情况下,函数从外部存储器读入局部变量进行计算,这时候,往往值得先把不是32 位的变量转换成32 位(至于把8 位或16 位变量扩展成32 位后,隐藏了原来可能的溢出异常这个问题,需要进一步的仔细考虑)。
int wordinc (int a)
{ return a + 1;
}
wordinc
ADD a1,a1,#1
MOV PC,LR
short shortinc (short a)
{ return a + 1;
}
shortinc
ADD a1,a1,#1
MOV a1,a1,LSL #16
MOV a1,a1,ASR #16
MOV PC,LR
char charinc (char a)
{ return a + 1;
}
charinc
ADD a1,a1,#1
AND a1,a1,#&ff
MOV PC,LR 答 15: 一般局部变量用32位。考虑性能的场合用汇编吧,
rvct2.0开始提供了嵌入式汇编,非常好用的:) 答 16: 真是抛银引金啊大家都是金玉良言啊,我感觉有点收获。
如果变量是保存在外部RAM(8位或16位接口),那就没有必要全部使用32位了。
答 7: 大家还有别的意见吗? 一起讨论讨论吧。 答 8: 期待正在做一个项目,现在对RAM的使用充满了疑惑。期待大家讨论。 答 9: 从8位机上过来的,所以。一直大量使用8位方式。
当然,公司产品与外设(I2C、SPI....)关系非常密切,所以,理所当然使用8位。
多数情况下,没有对性能锱铢必较。
答 10: 以前看过某书上说,变量字长与芯片字长一样时,效率最高 答 11: 我之愚见对于32位的来说,最好是统一.即使不统一,也不要混合声明,要按照一定顺序来才好. 答 12: 一些看法ARM有点特殊,他不像x86架构保留一些历史残留,在x86中例如32bit的寄存器EAX(32bit)可分解出一个AX(16bit),还有AX何以分解为AH和AL两个8bit寄存器,几乎每种寄存器都可以作为操作数独立操作,但是现行32bit编译器(例如VC)似乎都愿意把他们作为32bit变量运算,这样就会使得存取数据时候需要额外的“与或”“移位”操作修正变量从而会降低了一些效率;
而对于本身就是8bit宽度的51单片机来说,最快的处理当然是8bit变量,个人认为随着变量宽度递增其代码时空效率也几乎线性递减的。
在过去很长一段时间受一些win32编译器影响也认为ARM使用非机器字长的变量进行运算会明显降低代码的时空效率,但是后来发现这个差距变得非常小,现在的ARM出生没有什么历史残留,基本寄存器就是32bit的,因此绝大多数运算不管变量宽度都是用同一套指令操作,效率没有明显的差别,而且在数据存取的指令集中str/ldr都是允许带b或者h等后缀使得8bit或者16bit数据存取都可以使用一条指令完成;(以上针对片内flash/RAM,ADS编译器提出)
就ADS而言,其实真正的代码时空效率问题会由于改变了默认对齐引起的,常见的位域、压缩的结构(人为改变结构成员按机器字长对齐的规则)都是牺牲性能换取编程操作方便或者RAM空间的,这时候访问这些数据成员就需要额外的时空代价了。
就自己的观点看来:
1,如没有特殊原因尽可能使用与机器字长一致的变量,特别是临时变量;
2,若不是为了满足硬件寄存器分布映射、固定的软件协议等特殊需要(包括资源紧张)时不要人为改变数据存储对齐宽度;
3,对于ARM编程不要片面追求效率; 答 13: 说的也是,外围大多是8位的器件,包括串行的,并行的 UART IIC SPI的缓冲区,我都用8位的 答 14: 下面的文字引自ARM中国的一篇文档。一般情况下人们总是设法使用short 或char 来定义变量以节省存储器空间;但是,当一个函数的局部变量数目有限的情况下,编译器会把局部变量分配给内部寄存器,每个变量占用一个寄存器。这样,使用short 和char 型变量不但起不到节省空间的作用,还会带来其他的副作用,
请看图2。假定a1 是任意可能的寄存器,存储函数的局部变量。同样完成加一的操作,32 位的int 型变量最快,只用一条加法指令。而8 位和16 位变量,完成加法操作后,还需要在32 位的寄存器中进行符号扩展,其中带符号的变量,要用逻辑左移(LSL)接算术右移(ASR)两条指令才能完成符号扩展;无符号的变量,要使用一条逻辑与(AND)指令对符号位进行清零。所以,使用32 位的int 或unsigned int 局部变量最有效率。某些情况下,函数从外部存储器读入局部变量进行计算,这时候,往往值得先把不是32 位的变量转换成32 位(至于把8 位或16 位变量扩展成32 位后,隐藏了原来可能的溢出异常这个问题,需要进一步的仔细考虑)。
int wordinc (int a)
{ return a + 1;
}
wordinc
ADD a1,a1,#1
MOV PC,LR
short shortinc (short a)
{ return a + 1;
}
shortinc
ADD a1,a1,#1
MOV a1,a1,LSL #16
MOV a1,a1,ASR #16
MOV PC,LR
char charinc (char a)
{ return a + 1;
}
charinc
ADD a1,a1,#1
AND a1,a1,#&ff
MOV PC,LR 答 15: 一般局部变量用32位。考虑性能的场合用汇编吧,
rvct2.0开始提供了嵌入式汇编,非常好用的:) 答 16: 真是抛银引金啊大家都是金玉良言啊,我感觉有点收获。
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
vscode+cmake搭建雅特力AT32L021开发环境被打赏30分 | |
【换取逻辑分析仪】自制底板并驱动ArduinoNanoRP2040ConnectLCD扩展板被打赏47分 | |
【分享评测,赢取加热台】RISC-V GCC 内嵌汇编使用被打赏38分 | |
【换取逻辑分析仪】-基于ADI单片机MAX78000的简易MP3音乐播放器被打赏48分 | |
我想要一部加热台+树莓派PICO驱动AHT10被打赏38分 | |
【换取逻辑分析仪】-硬件SPI驱动OLED屏幕被打赏36分 | |
换逻辑分析仪+上下拉与多路选择器被打赏29分 | |
Let'sdo第3期任务合集被打赏50分 | |
换逻辑分析仪+Verilog三态门被打赏27分 | |
换逻辑分析仪+Verilog多输出门被打赏24分 |