打印

(修改)导致STM32芯片指令速度变化的问题分析过程

[复制链接]
楼主: ifreecoding
手机看帖
扫描二维码
随时随地手机跟帖
21
本帖最后由 Ryanhsiung 于 2012-4-1 15:04 编辑
不希望优化的,至少要加个volatile,否则你添加了其他代码,重新编译,可能这个delay函数又变样了……
void DEV_DelayMs(volatile U32 uiMs)
{
    volatile unsigned int i;
    volatile unsigned int j;

    j = ...
mohanwei 发表于 2012-4-1 14:41


f无关优化问题、中断,先前我也遇到了,一直没解决问题!!
谢谢LZ

使用特权

评论回复
22
chenbb8| | 2012-4-1 14:57 | 只看该作者
黔驴技穷,是个贬义词。用词不当

使用特权

评论回复
23
Ryanhsiung| | 2012-4-1 15:03 | 只看该作者

使用特权

评论回复
24
mcu_cpp| | 2012-4-1 15:29 | 只看该作者
STM8 也同样存在这个问题。

使用特权

评论回复
25
ifreecoding|  楼主 | 2012-4-1 15:49 | 只看该作者
刚才查了一下STM32的flash手册,手册中有下面的描述:
“Cortex-M3在I-Code总线上取指令,在D-Code总线上取数据。预取指令块可以有效地提高对ICode
总线访问的效率。预取缓冲器包含两个数据块,每个数据块有8个字节;预取指令(数据)块直接映像到闪存中,因为数据块的大小与闪存的宽度相同,所以读取预取指令块可以在一个读周期完成。设置预取缓冲器可以使CPU更快地执行,CPU读取一个字的同时下一个字已经在预取缓冲器中等候,即当代码跳转的边界为8字节的倍数时,闪存的加速比例为2。”

这里面也提到了8字节跳转的问题,在这段代码里是有几个跳转,几个跳转的叠加可能就出现了1:0.8这个执行效率了,如果是这样的话,应该说这个延迟是STM32设计造成的,不算它的一个bug。
等我今天晚上回家后把这部分反汇编代码找出来分析一下,然后再贴出来。

另外多谢各位参与讨论

使用特权

评论回复
26
zaj1017141116| | 2012-4-1 15:49 | 只看该作者
真强

使用特权

评论回复
27
cool_coder| | 2012-4-1 15:53 | 只看该作者
或者,把CPU时钟频率降到不需要加入闪存等待周期的程度再试试?

使用特权

评论回复
28
ifreecoding|  楼主 | 2012-4-1 16:00 | 只看该作者
to 20楼,我考虑了,我在文中已经提到了tick中断的影响,因此在另外一个没有tick中断的系统了又测试了一次,涛声依旧。
串口数据打印是打印到内存中,然后在idle任务中再向串口打印

另外,你所说的优化要加volatile,我觉得volatile关键字是强迫重新读取数据源,这个与优化没有必然的联系。
to 4楼,在32位机上int与long一般是一样的。
to 9楼,可移植性是相对的,就比如说嵌入式系统一般不会采用页机制,如果也考虑这方面的话也许就画蛇添足了,关键看应用背景

使用特权

评论回复
29
ifreecoding|  楼主 | 2012-4-1 16:04 | 只看该作者
黔驴技穷,是个贬义词。用词不当
chenbb8 发表于 2012-4-1 14:57


幽默感啊,大哥,呵呵!

使用特权

评论回复
30
来与君| | 2012-4-1 16:18 | 只看该作者
对于10mS级以上的定时需求,我只相信定时器。

使用特权

评论回复
31
idterminator| | 2012-4-1 17:16 | 只看该作者
1,变量类型让人很困惑,该长的你弄成短的,该短的你弄成长的,而且没有考虑溢出;
2,延时的方法让人很费解,
如标题,既然LZ那么关注芯片效率,为什么还要用这种延时方法呢?
即使用这种延时方法,为什么不用for(i = 0;i<j ; i++)
break有什么用意呢,或者说好处,请教一下。

使用特权

评论回复
32
nongfuxu| | 2012-4-1 17:21 | 只看该作者
有时间读一下此贴。

使用特权

评论回复
33
相信哥咯| | 2012-4-1 19:18 | 只看该作者
楼主,我下载过你的文档,很不错:lol

使用特权

评论回复
34
Txapp| | 2012-4-1 20:11 | 只看该作者
STM32延时1ms以上不用定时器还想准确?32位机int一般跟long“一般”一样,有分析问题的劲保险点写long int吧。

使用特权

评论回复
35
kseeker| | 2012-4-1 23:57 | 只看该作者
分析的精神是值得肯定的,但这个问题出现的原因在于基础知识不足,对CPU的工作原理没有充分的了解。
LZ这段代码在“原始”的处理器上可以工作,但在稍微高级一点的CPU上根本就行不通。高级的CPU都有各种对齐问题,缓存命中问题,核心/流水线调度问题,分支预测命中问题,种种不确定行导致代码执行时间根本就不能确定。

在PC上如果你的变量访问时L1,L2,L3缓存连续未命中,内存访问缺页从而去读硬盘这时间可就没谱了(这完全有可能发生)。这还不说如果赶上进程切换,你的代码被饿死上几个小时都完全有可能。

使用特权

评论回复
36
ifreecoding|  楼主 | 2012-4-2 00:39 | 只看该作者
分析的精神是值得肯定的,但这个问题出现的原因在于基础知识不足,对CPU的工作原理没有充分的了解。
LZ这段代码在“原始”的处理器上可以工作,但在稍微高级一点的CPU上根本就行不通。高级的CPU都有各种对齐问题,缓 ...
kseeker 发表于 2012-4-1 23:57




哎,各位都是大牛啊,我敢保证,任何一个人提出一点建议来,100个大牛会有100种意见。

你说的那些我不敢说我全知道,但我也定位过cache写入不一致的问题。

很多事情要看应用场景,一个单片机连MMU都没有,就非得说代码没考虑cache一致性问题,说代码移植性不好,这都哪和哪的事情啊,还和我扯L1,L2,L3,你给我找找哪个STM32-M系列的芯片有L3的,有L2的也行,让我长长见识。还访问缺页,有页机制么就缺页,哪个嵌入式设备使用页机制,大哥,帮我推荐一下

你们都是大牛行了吧,牛B就自己写点什么上来给大家分享一下,觉得自己哪些代码写的好就发上来。一些基本概念谁都知道,能真正理解写出代码就是另一回事了

使用特权

评论回复
评论
xlsbz 2014-9-24 09:26 回复TA
说得好 
37
Simon21ic| | 2012-4-2 01:11 | 只看该作者
貌似单片机等级的东西是不会有MMU的。
21ic牛人应该不少,我什么时候也准备一些有意思的题目来讨论讨论。

使用特权

评论回复
38
lost1421| | 2012-4-2 10:23 | 只看该作者
这种delay延时大部分是不可靠的,如果运行时,中间发生了中断,后果可想而知!

使用特权

评论回复
39
kevin_ares| | 2012-4-2 22:34 | 只看该作者
我最近遇到一个串口问题
usart1用DMA发送数据
DMA完成中断能产生,示波器量STM32引脚却没数据

加几行码编译,随便加,又行了
再加几行编译,又不行了
搞得抓狂,求解

使用特权

评论回复
40
willwu0327| | 2012-4-3 08:49 | 只看该作者
學習一下~
但為何不用sys tick?雖然會比較吃系統資源,但它卻是很準確的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则