3

我正在为 MSP430 编写嵌入式代码,使用最高优化级别的 IAR 编译器(速度或大小不会改变任何东西)。

我将一个函数定义为静态的,然后在同一个文件中只引用它一次。由于该函数具有内部链接,并且仅使用一次,因此我希望优化器执行内联扩展。我看不出有理由不这样做。

该函数很短,它产生 16 个字的机器码。它是从 ISR 调用的。添加 inline 关键字使函数内联,但优化器似乎需要提示。内联将两个push/ pops 保存到堆栈中, onecalla和 one reta

我是否期望执行内联扩展(即使没有inline关键字),还是我错过了什么?


编辑:更多测试表明内联扩展取决于函数的大小,并且阈值非常低。它似乎是大约 15 或 16 个字的机器代码。在此之上,如果没有给出关键字,优化器不会扩展。

我仍然不明白为什么它不会(可读性不应该成为优化器的关注点,不是吗?),但我知道 IAR 只能回答这个问题。

4

3 回答 3

2

我正在使用几年前的 IAR ARM 编译器版本(v5.2);我不知道其中有多少可能适用于 MSP430 编译器。

inlineIAR ARM 编译器使用任何“高”优化设置-Oh(平衡)、-Ohs(速度)或(大小)内联未明确标记的-Ohz静态函数 - 包括具有一定复杂性的静态函数(例如循环)。

当然,我想有一些静态函数没有内联,但快速检查表明 IAR 编译器通常正在执行此优化。

所以,我希望编译器内联你的静态函数——但如果你想依赖这些优化,我认为你需要检查输出(就像你所做的那样)。当然,哪些优化以及如何应用它们完全取决于编译器,所以只有 IAR 才能真正回答优化是否“应该”发生的问题(或者为他们为什么可能决定不应该进行辩护)。如果您认为 IAR 没有适当地执行此优化,您可能想与 IAR 交谈。他们可能会给您一个提示,说明为什么在这种特殊情况下没有发生这种情况。

于 2011-02-18T19:36:06.267 回答
2

编译器不需要内联代码(即使明确标记inline),优化器的复杂程度和策略也各不相同。所以这对于您的编译器供应商来说确实是一个问题(查阅文档也可能会有所帮助)。

如果函数特别大,编译器可能已经决定避免函数调用开销在整个方案中是微不足道的。

您的编译器可能有一个_force_inline关键字或类似的,这将被视为一个指令而不是一个建议(inline通常在大多数编译器上)。

不内联的一个可能论点是在维护下保持确定性性能。如果稍后的第二次引用导致它不再内联,您的代码执行速度可能会以不利于应用程序性能要求的方式发生变化,而保持内联可能会显着影响代码大小。

[编辑]阅读文档,在您的编译器上,#pragma inline=forced在函数定义之前需要该指令,否则内联取决于优化器启发式。即使在强制的情况下,内联也不会在低优化或没有优化时发生。

于 2011-02-19T08:42:23.963 回答
0

根据此线程中的 IAR 员工IAR 大小优化和内联函数

正式地,仅当编译器在头文件或同一源文件中看到定义时才支持它。但是,作为一项实验,我们尝试了一种称为“多文件编译”的方法,您可以在其中将多个 C 文件同时提供给编译器,允许它在编译单元之间内联。请注意,这纯粹是实验性的,IDE 不支持它。

...

就个人而言,如果我今天编写应用程序,我不会使用 --mfc 选项。相反,我会将我想内联的函数放在头文件中,就像你在使用内联方法编写 C++ 类定义时所做的那样。

于 2012-02-20T17:18:06.243 回答