在C语言中内联一个函数到另一个内联函数中

8
我目前有内联函数调用另一个内联函数(一个简单的4行大的getAbs()函数)。然而,通过查看汇编代码,我发现"大"的内联函数被很好地内联了,但编译器使用bl跳转来调用getAbs()函数。
难道不可能在另一个内联函数中内联一个函数吗?顺便说一下,这是嵌入式代码,我们没有使用标准库。
编辑:编译器是WindRiver,并且我已经检查过内联将是有益的(4条指令而不是+-40)。

你使用的编译器是什么?通常有一些方法可以强制进行内联。我假设你已经对代码进行了分析,并且非常确信内联将会有益。在GCC中,可以使用__attribute__((always_inline))来实现这一点。 - stinky472
我可以问一下你为什么关心编译器做出的决策吗?你是否对代码进行了分析,并发现那个跳转指令的开销正在影响性能? - JeremyP
5个回答

8
inline关键字只是对编译器的一个“建议”,并不是更多的东西。编译器可以自由地接受这个建议,完全忽略它,甚至向您撒谎,并告诉您正在执行此操作,而实际上并没有。
强制代码成为内联的唯一方法就是将代码编写为内联。但是即使如此,编译器也可能决定它知道得更好,并决定将其移到另一个函数中。在为您的特定源生成可执行代码方面,它有很大的灵活性,前提是它不改变它的语义。
现代编译器比大多数开发人员手动编写汇编代码能够生成更好的代码。我认为inline关键字应该走与register关键字相同的路线。
如果您看过gcc在疯狂的优化级别下的输出,您会理解为什么。它已经生成了我从未梦想过的代码,并且花费了我很长时间才理解。
顺便说一下,请查看此处,了解gcc实际具有的优化,其中包括许多包含文本“inline”或“inlining”的优化。

我猜测,当编译器在功能或时间方面无法处理内联函数的情况时,可能添加了内联关键字。但是今天的编译器可能已经能够自己解决这个问题,即使没有内联关键字也可以。只是猜测。 - Lasse V. Karlsen
gcc是否支持基于配置文件的优化?当不使用这些时,向gcc提示内联可能会有很大帮助。这是基于对函数是否会被频繁调用的了解,即使是最聪明的编译器也无法判断。 - Peaker
“inline”关键字仍然很有用,因为它允许您在多个翻译单元中定义相同的函数,只要使用相同的定义(实际结果是您可以将“inline”函数定义放入头文件中,从而允许跨模块内联)。 - caf
非常正确!"inline"关键字应该和"register"关键字走相同的路线。 - TonySalimi

8

根据您使用的编译器不同,您可以通过一些方式来鼓励编译器更愿意进行内联,例如使用gcc时,您可以使用__attribute__ ((always_inline)),使用Intel ICC时,您可以使用icc -inline-level=1 -inline-forceinline,而在苹果的gcc中,则可以使用gcc -obey-inline


1

@gramm: 有很多情况下,内联并不一定对你有好处。大多数编译器使用一些非常先进的启发式算法来确定何时进行内联。在讨论内联时,最简单的想法是,相信你的编译器能够生成最快的代码。


0

我最近遇到了一个非常类似的问题,阅读这篇文章给了我一个疯狂的想法。为什么不使用一个简单的预编译(一个简单的正则表达式就可以完成)代码解析器来解析函数调用以实际将源代码内联。使用像 /inline/ /end_of_inline/ 这样的标记,这样你就可以使用正常的 IDE 功能(如果你正在使用或可能使用 IDE)。 将其包含在您的构建过程中,这样您就有了可读性优势,同时消除了编译器的假设,即您只是大多数开发人员一样出色,不理解何时进行内联。

然而,在尝试此操作之前,您应该先查看编译器的命令行选项。


-1
我建议,如果你的getAbs()函数(听起来像绝对值,但你真的应该在问题中展示代码……)有4行长,那么你要担心的优化比代码是否被内联还要大得多。

你要么是在说调用函数的开销对于短函数来说不那么重要,要么是在说拥有短函数是一件普遍不好的事情,无论哪种方式,你都会得到-1。 - Pete Kirkham
不,我的意思是一个糟糕的abs()实现比编译器无法内联它对性能的影响更大。(事实上,编译器不内联它可能是正确的做法..) - R.. GitHub STOP HELPING ICE
和Pete一样。50条指令而不是5条指令是一个巨大的开销,通常在循环中使用时会变得明显。我不确定你是否习惯于使用微控制器。 - gramm
让我们看看 - 一个函数声明一行,一个左括号一行,一个return语句x < 0 ? -x : x;一行,一个右括号一行 = 4行。如果可以,请编写少于四行的abs函数。 - Pete Kirkham
@PeteKirkham double abs(double x) { return x < 0.0 ? -x : x; } // 一行代码实现的绝对值函数。:D - Anurag Kalia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接