原创 【分析】STM32的代码,跑在RAM里快?还是跑在Flash里快?

2008-8-28 14:12 9638 13 4 分类: MCU/ 嵌入式

这肯定是很多人关心的问题,下面通过一个例子看看会有什么样的结论:





测试手段如下:


主循环一直在做一个变量的自加(sum1++),当然前提保证不会溢出。


用Cortex-M3内部的Systick计数,以一秒钟为限,这个sum1的数值大小,可以判断哪种方式比较快。为了严密,我们观察第一秒到第二秒之间的计数效果;而不是从第0秒到第1秒(因为使能Systick到真正开始执行sum1++可能有间隙)。在第一次进入Systick的ISR时,记录下sum1的值;第二次进入Systick的ISR时,再次记录sum1的值,两次值之差即为一秒钟间隔中sum1执行了多少次自加。由此看出哪种方式比较快。


同样的测试前提:Prefetch Buffer Enable + Flash Latenty="2" (根据Flash Programming Manual中要求的那样,当48MHz<SYSCLK<=72MHz时,对flash的访问插入两个等待周期)







测试结果如下:
不对代码优化,在RAM中执行程序:sum1计数69467/秒
不对代码优化,在FLASH中执行程序:sum1计数43274/秒 (Flash里跑得慢)


/***********循环体内代码为N个以下的block*************/
(1)LDR R0,[PC, #0x154]
(2)LDR R1,[PC, #0x154]

(3)LDR R1,[R1,#0]
(4)ADDS R1, R1,#0x1

(5)STR R1,[R0, #0]

    ......
/****************************************************/

打开速度优化开关,在RAM中执行程序:sum1计数98993/秒
打开速度优化开关,在FLASH中执行程序:sum1计数115334/秒 (Flash里跑得快)

/***********循环体内代码为N个以下的block*************/
(1)LDR R1,[R1,#4]
(2)ADDS R1, R1,#0x1
(3)STR R1,[R0, #0]
    ......
/****************************************************/





结论就是:


1)程序运行在RAM里速度快还是运行在Flash里速度快,不是绝对的一概而论的,取决于代码;


2)就以上两种具体的代码情况来说,我觉得无优化时,如果在Flash里执行:(1)(2)的取指(读flash)->译码->执行(读flash);取指和执行阶段flash的目标地址不是连续的,因此是non-sequencial access,所以会很慢;
打开优化时,(1)(2)(3)都不会造成flash的non-sequential access,所以在flash里的优势(取指和取数据走不同的总线ICode和DCode以及Prefetch)就体现出来了。





再进一步的分析,又有这样一些结论:


没有优化时,指令执行时要到Flash中取常数,结果造成指令预取队列的取指中断,取完常数后需要重新填充指令预取队列,而Flash访问需要插入等待周期,当然时间就比较长了。


经过代码优化后,指令执行时不用再到Flash中取常数,指令预取队列不会被打断,而Flash访问需要插入等待周期的效应被下面贴子中介绍的取指缓冲区抵消,所以自然速度就快了;而这个时候在RAM中执行反而慢了是因为RAM不在ICode总线上,从RAM取指需要绕一圈,当然要比在ICode总线上的Flash慢了。


关于Flash的性能,请看我的另一篇分析:【分析】STM32从Flash中运行程序的时序分析





另外,STR9与STM32的总线架构是一样的,这里有一个在STR9上实现的FFT函数的实测数据,可以进一步说明在Flash中运行代码可以比在RAM中快!


在ST的网站上有一个DSP的函数库,这是它的文档《STR91x DSP library (DSPLIB)》,在这篇文档中有一节讨论FFT运算速度的,那里给出了实际的运算时间比较,摘录如下:

Radix-4
Complex FFT
Operation ModeCycle CountMicroseconds
64 PointProgram in Flash & Data in SRAM270128.135
64 PointProgram & Data in SRAM343235.75
64 PointProgram & Data in Flash370538.594
256 PointProgram in Flash & Data in SRAM13740143.125
256 PointProgram & Data in SRAM18079188.323
256 PointProgram & Data in Flash19908207.375

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

用户1090342 2009-5-28 11:23

这是个好问题。因为在ARM7中可以说程序在RAM中可以比在Flash中快,很多学过ARM7的人把这个概念带到了STM32中,所以会关心这个问题。

用户187751 2009-5-26 15:09

请问 为什么这是“这肯定是很多人关心的问题,”?
相关推荐阅读
用户1090342 2010-08-05 12:33
使用STM32定时器输出任意相位差的方波
记得曾经有不少人问起这个问题,方法十分简单,不用说明,看图即知(这里画了2路输出,同样道理可以产生3路甚至4路输出)。此方法不但可以在STM32上实现,因为STM8定时器的多数功能与STM32一样,所...
用户1090342 2010-05-06 16:11
STM32的功能引脚重映射和复用功能
STM32中有很多内置外设的输入输出引脚都具有重映射(remap)的功能,本文对一些在使用引脚重映射时所遇到的有关问题加以说明。我们知道每个内置外设都有若干个输入输出引脚,一般这些引脚的输出脚位都是固...
用户1090342 2010-04-23 11:04
改正了每次只能发送一个字节的USB虚拟串口例程
目前发布的STM32_USB-FS-Device_Lib中有一个USB虚拟串口的例程,这个例程演示了把STM32配置为一个USB虚拟串口设备,STM32从它的USART接口接收数据并通过USB传送到上...
用户1090342 2010-03-06 12:30
STM32定时器的预装载寄存器与影子寄存器之间的关系
本文的说明依据STM32参考手册(RM0008)第10版:英文:http://www.st.com/stonline/products/literature/rm/13902.pdf中译文:http:...
用户1090342 2010-02-26 12:18
使用BSRR和BRR寄存器直接操作STM32的I/O端口
STM32的每个GPIO端口都有两个特别的寄存器,GPIOx_BSRR和GPIOx_BRR寄存器,通过这两个寄存器可以直接对对应的GPIOx端口置'1'或置'0'。GPIOx_BSRR的高16位中每一...
用户1090342 2010-01-28 16:23
如何使用STM32的USB库支持延迟HID的GET_REPORT请求
首先,请参考我的另一篇博客:以HID的SET REPORT为例说明如何使用STM32的USB库支持控制端点0如果要支持HID的GET_REPORT请求,按照上一篇博客中的说明,只需要在STM32 US...
EE直播间
更多
我要评论
2
13
关闭 站长推荐上一条 /3 下一条