打印

Keil优化导致错误频生

[复制链接]
7862|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
goooogle|  楼主 | 2009-12-29 11:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我写程序是按照"稳打稳扎""步步为营"的战略,将功能要求各个分解分布实现,每一个模块逐个调试实现再继续写下一个模块.可是当代码写到40K附近时就总会出现一些莫名其妙的问题,比如原先完全正常调试通过的功能不正常了,比如软件模拟一个串行时序,时序就不对了,延时函数我开始都是用示波器观测确定的(观察此函数反汇编没有与之前不同),找了好久的问题最后尝试修改这个函数所在文件优化等级,将速度优先改为代码优先,嘿,好了.
    可是后面接着写又有其它问题了,比如串口接收,每接收到一个字节都计算CRC,一帧结束后校对CRC,原本好好的,增加代码后在某一特殊情况下串口接收不正确了(在其它情况下均正常),设置断点发现计算CRC的函数返回的结果根本就不正确,在该函数内设置断点发现程序都没进入这个函数了.但是我看反汇编确实有进入此函数的代码生成.于是我再次修改此函数所在文件的优化等级,修改为0级后就一切正常了.
    KEIL的默认优化级别是8级速度优先.
    我就有个疑问,为什么在程序小的时候没出现问题,代码越长就出现这样那样的优化问题?更要命的时,在代码很长后写程序如果不正常怎么知道是自己写的程序本身有问题还是KEIL的优化干的坏事?

相关帖子

沙发
voidx| | 2009-12-29 11:36 | 只看该作者
本帖最后由 voidx 于 2009-12-29 11:44 编辑

GCC,IAR从来都是最高优化,也没发现啥问题。
KEIL不用,不清楚。

程序优化如果出问题,99.999%是程序本身有问题(或者说程序不严谨,不标准)。

优化的目的,不管中间过程如何,以最快的速度(或者最小代码量,或者两个之间某个平衡),执行完代码并输出。

不严谨的延时函数,在优化等级高的时候,会被当做无意义的代码直接kill掉。

使用特权

评论回复
板凳
goooogle|  楼主 | 2009-12-29 12:28 | 只看该作者
请教LS,什么样的延时函数是"严谨的"?
如果把本该执行的函数都优化成不执行了,我觉得这不是程序问题而是优化错误

使用特权

评论回复
地板
HWM| | 2009-12-29 12:39 | 只看该作者
要严格按自己思路按部就班的执行的东东,建议用嵌入汇编的方法去做。就算是无优化的编译都很难做到完全一步不差地遵循设计者的步骤去走一条完全相同的路。通常编译只求“语义”上的一致,而不是步骤上的一致。只要步骤不违反语义,就可能篡改步骤。

使用特权

评论回复
5
goooogle|  楼主 | 2009-12-29 13:37 | 只看该作者
C语言本来就是按部就班的一条一条...编译器只能想办法让生成的代码更小更快,而不是该干的事不干了:L

使用特权

评论回复
6
HWM| | 2009-12-29 13:45 | 只看该作者
C语言本来就是按部就班的一条一条...编译器只能想办法让生成的代码更小更快,而不是该干的事不干了:L
goooogle 发表于 2009-12-29 13:37

如果一件所谓“该干的事”其结果没被使用,编译通常会将其“无视掉”的。还有就是,延迟和未用空间的占用,这些都是编译认为“不该干的事情”,因为其和编译的效率原则相背。

使用特权

评论回复
7
andirong| | 2014-1-15 16:30 | 只看该作者
我也支持楼主的,你功能都不能拿实现,那优化又有什么用呢?要是提示降低优化等级才人性化

使用特权

评论回复
8
chenbb8| | 2014-1-15 17:25 | 只看该作者
andirong 发表于 2014-1-15 16:30
我也支持楼主的,你功能都不能拿实现,那优化又有什么用呢?要是提示降低优化等级才人性化 ...

理想是美好的,现实是残酷的。

部分编译器的优化选项非常细致,可以观察到某个优化级做了哪些优化,也可以DIY自己的优化。
但是你是要编译器通知你自己在什么地方做了哪些优化么,那可是超级多的提示,烦死人那种,
看到那么多的提示,到时候估计你又要喊不人性化了。

编写严谨的代码,适应各种条件才是王道。

使用特权

评论回复
9
mohanwei| | 2014-1-15 17:35 | 只看该作者
又见延时函数……rolatile是好东西,变量前都加一个……

使用特权

评论回复
10
kseeker| | 2014-1-15 19:27 | 只看该作者
goooogle 发表于 2009-12-29 13:37
C语言本来就是按部就班的一条一条...编译器只能想办法让生成的代码更小更快,而不是该干的事不干了 ...

C语言不要求语句按顺序执行,C语言也不要求变量按顺序被访问,C语言更不能保证语句执行的时间,C语言甚至不要求语句被生成。
C语言仅仅要求“从外部来看结果不变”,大致来说,这相当于保证那些volatile的变量按顺序被读取和修改。

使用特权

评论回复
11
wolension| | 2014-1-16 09:14 | 只看该作者
andirong 发表于 2014-1-15 16:30
我也支持楼主的,你功能都不能拿实现,那优化又有什么用呢?要是提示降低优化等级才人性化 ...

难道你要求编译器先把8级优化产生的代码烧到芯片测试有没有问题,运行的结果对不对,然后告诉你结果不行,要降低优化等级5级?
很多编译器手册都会告诉你每一级优化会干些什么事,开了最高级优化,像下面的代码:
u8 i;
for(i=0;i<100;i++);
你开优化要求编译器帮你节省点程序空间,编译器发现你以上代码什么都没干,帮你优化掉,那不是很正常吗?

使用特权

评论回复
12
xlsbz| | 2014-1-16 14:25 | 只看该作者
优化没问题,你代码写的有问题。

使用特权

评论回复
13
weiyuliang| | 2014-6-14 14:46 | 只看该作者
个人经验,关于优化最开始一般怀疑编译器的问题。最后都是自己代码不够强壮导致

使用特权

评论回复
14
ningling_21| | 2014-6-14 16:41 | 只看该作者
有时由于使用的(全局变量定义在内部RAM)内部RAM数量过多就会导致异常现象出现...

使用特权

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

本版积分规则

5

主题

183

帖子

1

粉丝