硬汉嵌入式论坛

 找回密码
 立即注册
查看: 376|回复: 9
收起左侧

[IAR] 关于编译器的优化等级是否应该开到最高的讨论

[复制链接]

7

主题

48

回帖

69

积分

初级会员

积分
69
发表于 2024-4-26 22:19:02 来自手机 | 显示全部楼层 |阅读模式
国外编译器设计大佬的讨论。
英文原文:
Well, the pedantic statement about optimization is:
If your program has a defined behavior according to the C standard and avoids any undefined or unspecified behavior and works as intended with no optimization, then it will also have the same behavior with full optimization and just be smaller and/or faster.


However, programmers make lots of mistakes and often use code constructs, which already are deeply in the area of undefined behavior. However, that code often works just by coincidence if the compiler is not optimizing too much. Some typical errors are:
exchanging data between interrupts or rtos tasks or exceptions with main code without the use of volatile (or memory barriers)
bad type casting with pointers
undefined use of memory
pointer to stack memory after return from function
pointer to malloc-ed memory, which is already free-d
use of memory with uninitialized or corrupted pointers
array overflow/underflow
use of uninitialized variables
bad assumptions, that in certain code sections no interrupts will happen
bad assumptions about "this variable is changed before that variable", and you expect this to be also true when looking at it from another context (interrrupt / exception / rtos task / main code)
Without optimization or low optimization levels, it happens surprisingly often, that these common errors have no bad consequence.


However, the whole specification of C is based on the assumption that the compiler can produce a heavily optimized result. The specification defines a term what is called "observable behavior". Basically "observable behavior" are just (read or write) accesses to volatile or I/O functions through the standard libraries. This is also why also all the processor special function registers (including those for the pins) are defined as volatile. And the specification then defines, that when you theoretically execute your program line by line on an abstract machine and you record a certain sequence of observable behaviors, and the real assembled program on the real device just has to reproduce this same sequence of observable behaviors. Between those observable, it can do everything it wants. In particular it can remove any code which is not relevant for producing that sequence of observable behaviors or replace it with more efficient code.

Furthermore, the compiler is allowed to assume, that its code is executed uninterrupted. So, it does not have to expect any interrupt, any exception or any rtos task switch or some hardware in the background which is changing the content of some memory. If there is such a thing, then it is your responsibility to tell the compiler about every possible effect, which such an interruption of the regular code execution might have or which the hardware in the background has, by declaring the possible affected things volatile.


I would recommend: Develop your code always with the highest optimization levels, which is the exact same optimization setting which you are going to release. Only if you have a serious problem, which you need to debug, then go temporary down to a lower setting like -Og or -O1 or -O0, and try to find out what is wring. But don't forget to go back to the high setting afterwards.

中文译文:
好吧,关于优化的迂腐陈述是:
如果您的程序根据C标准定义了行为,避免了任何未定义或未指定的行为,并且在没有优化的情况下按预期工作,那么它也会在完全优化时具有相同的行为,并且只是更小和/或更快。


然而,程序员犯了很多错误,并经常使用代码结构,这些代码结构已经深深地处于未定义的行为领域。然而,如果编译器没有进行太多优化,该代码通常只是巧合。一些典型的错误是:
在中断或rto任务之间交换数据,或使用主代码的例外,而不使用易失性(或内存障碍)
带有指针的不良类型铸造
未定义的内存使用
从函数返回后堆栈内存的指针
指向malloc-ed内存的指针,它已经是free-d
使用未初始化或损坏指针的内存
数组溢出/溢出
使用未初始化的变量
糟糕的假设,在某些代码部分中不会发生中断
关于“此变量在该变量之前更改”的错误假设,您预计从其他上下文(中断/异常/rtos任务/主代码)查看时也是如此
如果没有优化或低优化水平,这些常见错误不会产生不良后果,这出人意料地发生。


然而,C的整个规范是基于编译器可以产生高度优化结果的假设。该规范定义了一个术语,即所谓的“可观察行为”。基本上,“可观察行为”只是通过标准库(读写)访问volatable或I/O函数。这也是为什么所有处理器特殊功能寄存器(包括引脚的寄存器)都被定义为易失性。然后,规范定义了,当您在抽象机器上逐行执行程序时,您记录了一定的可观察行为序列,而真实设备上的真实组装程序只需重现同一顺序的可观察行为。在那些可观察到的人之间,它可以做它想做的一切。特别是,它可以删除任何与产生该可观察行为序列无关的代码,或用更有效的代码替换它。

此外,允许编译器假设其代码是不间断地执行的。因此,它不必期望任何中断、任何异常或任何rtos任务开关或后台正在更改某些内存内容的硬件。如果有这样的事情,那么您有责任通过声明可能受影响的东西是易失的,告诉编译器所有可能的影响,这种常规代码执行的中断可能会产生什么,或者后台的硬件会有什么影响。


我建议:始终以最高的优化级别开发您的代码,这与您将发布的优化设置完全相同。只有当您遇到严重问题时,您需要进行调试,然后暂时下到较低的设置,如-Og或-O1或-O0,并尝试找出什么是拨。但别忘了事后回到高处。

评分

参与人数 1金币 +50 收起 理由
eric2013 + 50 赞一个!

查看全部评分

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106872
QQ
发表于 2024-4-27 08:10:12 | 显示全部楼层
谢谢楼主分享。
回复

使用道具 举报

0

主题

9

回帖

9

积分

新手上路

积分
9
发表于 2024-4-27 09:24:31 | 显示全部楼层
只要flash和ram空间不成问题,何必跟自己过不去,弄个-O0就行了,优化等级高了,调试都困难
回复

使用道具 举报

7

主题

48

回帖

69

积分

初级会员

积分
69
 楼主| 发表于 2024-4-27 11:03:52 来自手机 | 显示全部楼层
稳健的代码通吃每个优化等级,我的经验是代码在最高等级完美运行,调低后不会有什么问题,反之就不一定了。现在稍微严苛一点的行业,不都要求功能安全嘛,最好还是写无懈可击的代码。当然要求高,代价也高。
回复

使用道具 举报

75

主题

685

回帖

910

积分

金牌会员

积分
910
发表于 2024-4-27 13:49:27 | 显示全部楼层
依靠编译器优化不是一个明智的选择
回复

使用道具 举报

7

主题

48

回帖

69

积分

初级会员

积分
69
 楼主| 发表于 2024-4-27 14:05:53 来自手机 | 显示全部楼层
首先必须承认不能完全依赖编译器优化,最主要的还是工程师保证自己的代码足够精炼,符合规范,不能臃肿不堪,做好抽象和函数提炼,数据结构合理,算法做的足够高效。最后还是用高等级优化。最后绝大部分工程师用汇编写的代码,还不如高优化等级编译器生成的,即使精通汇编代码。
回复

使用道具 举报

1

主题

39

回帖

47

积分

新手上路

积分
47
发表于 2024-4-27 16:46:56 | 显示全部楼层
编译优化的目标并不会优化你的程序逻辑/算法,它只是在保证不改变你的程序逻辑的前提下,尽可能以高效的形式用机器语言表达出来。

用形像点的比喻:
你的代码:去开门
ASM: 去开门
C/C++: 伸手出左手,开门,把手放回口袋
Java:先跑1000米热身,伸出两只手,开门,去洗澡
Python: 向前走1000米,后退10公里,再回到原点(省略10W字)....开门,好累,先洗澡再去睡个觉

除了小汇编,没有哪门语言在翻译时不夹带私货的,在保证不改变你代码逻辑的前提下。编译优化会让编译器以尽可能高效的方式表达你的逻辑。
由于高级抽象表达形式会有隐含的执行条件、上下文、附加属性甚至是二义性,这给了编译器更多的机会从这种抽象表达中提取出核心逻辑,以等价的机器语言形式描述出来。
对于绝大多数不了解这些特性的初学者来说,似乎编译器有什么黑魔法,其实是他们根本不知道自己的写的代码是什么。

写代码不开优化,就像背着大象跑马拉松
回复

使用道具 举报

7

主题

48

回帖

69

积分

初级会员

积分
69
 楼主| 发表于 2024-4-27 18:09:28 来自手机 | 显示全部楼层
我是针对C和汇编的嵌入式编译器,其他语言没经验。
回复

使用道具 举报

1

主题

66

回帖

69

积分

初级会员

积分
69
发表于 2024-4-28 15:33:58 | 显示全部楼层
KEIL环境,我喜欢用 -O2 等级,不会优化的太离谱,还能去除一些没使用的函数啥的
回复

使用道具 举报

210

主题

1044

回帖

1684

积分

至尊会员

More we do, more we can do.

积分
1684
发表于 2024-4-29 10:53:29 | 显示全部楼层

IAR的优化等级说明:



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-8 09:52 , Processed in 0.315040 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表