【问题标题】:inline a function inside another inline function in C在 C 中的另一个内联函数中内联一个函数
【发布时间】:2011-03-10 00:16:44
【问题描述】:

我目前有内联函数调用另一个内联函数(一个简单的 4 行大 getAbs() 函数)。然而,我通过查看汇编代码发现“大”内联函数被很好地内联,但是编译器使用bl 跳转来调用getAbs() 函数。

不能在另一个内联函数中内联一个函数吗?顺便说一句,这是嵌入式代码,我们没有使用标准库。

编辑:编译器是 WindRiver,我已经检查过内联是有益的(4 条指令而不是 +-40)。

【问题讨论】:

  • 你用的是什么编译器?通常有一些方法可以强制内联。我假设您已经分析了您的代码并且非常有信心内联将是有益的。在 GCC 中,这可以通过 __attribute__((always_inline)) 来完成。
  • 我能问一下您为什么关心编译器做出的决定吗?您是否对代码进行了剖析,发现一条跳转指令的开销正在扼杀性能?

标签: c function inline


【解决方案1】:

inline 关键字是对编译器的建议,仅此而已。您可以随意采纳该建议,完全忽略它,甚至对您撒谎并告诉您它正在这样做,而实际上并没有。

强制代码内联的唯一方法是内联。但是,即便如此,编译器可能会认为它知道得更好,并决定将其转移到另一个函数中。它在为您的特定源生成可执行代码方面有很大的余地,只要它不改变它的语义。

现代编译器能够生成比大多数开发人员在汇编中手工制作的代码更好的代码。我认为inline 关键字应该与register 关键字走相同的路径。

如果您已经看到 gcc 在其疯狂优化级别的输出,您就会明白为什么。它产生了我做梦也想不到的代码,我花了很长时间才理解。

顺便说一句,检查this 了解 gcc 实际有哪些优化,包括许多包含“内联”或“内联”文本的优化。

【讨论】:

  • 我冒昧地猜测一下,当确定函数是否可以内联的任务对于编译器来说有点太大(无论是功能方面还是时间方面)时,添加了关键字),但今天的编译器可能能够自己解决这个问题,即使 inline 关键字不存在。不过只是猜测。
  • gcc 是否支持基于配置文件的优化?当不使用这些时,暗示 gcc 内联可能有帮助是很有意义的。这是基于函数是否会被称为 lot 的知识,最聪明的编译器仍然无法分辨。
  • inline 关键字仍然很有用,因为它允许您在多个翻译单元中定义相同的函数,只要您使用相同的定义(实际结果是您可以将inline函数定义到头文件中,允许跨模块内联)。
  • "inline 关键字应该和 register 关键字走相同的路径" --> 非常正确!
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    我建议如果您的 getAbs() 函数(听起来像绝对值,但您确实应该向我们展示带有问题的代码...)是 4 行长,那么您需要担心的优化比是否代码是否内联。

    【讨论】:

    • 要么你是说调用函数的任何开销对于短函数来说都不那么重要,要么你是说拥有短函数通常是一件坏事,无论你得到-1跨度>
    • 不,我是说 abs() 的糟糕实现比编译器无法内联它对性能的影响要大得多。 (实际上编译器可能通过不内联它来做正确的事情..)
    • 和皮特一样。拥有 50 条指令而不是 5 条指令是一个巨大的开销,并且在循环中使用时通常会变得很明显。我不确定你是否习惯使用微控制器。
    • 让我们看看 - 一行函数 decl,一行 {,一行 return x
    • @PeteKirkham double abs(double x) { return x
    【解决方案4】:

    根据您使用的编译器,您可以鼓励编译器减少内联,例如gcc 可以使用__attribute__ ((always_inline)),Intel ICC 可以使用icc -inline-level=1 -inline-forceinline,Apple 的gcc 可以使用gcc -obey-inline

    【讨论】:

      【解决方案5】:

      我最近遇到了一个非常相似的问题,阅读这篇文章给了我一个古怪的想法。为什么不拥有一个简单的预编译(一个简单的 reg ex 应该可以完成这项工作)代码解析器,它解析出函数调用以实际将源代码内嵌。使用 /inline/ /end_of_inline/ 之类的标签,以便您可以使用普通的 ide 功能(如果您正在使用或可能使用 ide. 将其包含在您的构建过程中,这样您就具有可读性优势,并且消除了编译器假设您只是一个优秀的开发人员并且不知道何时内联的假设。

      尽管如此,在尝试此之前,您可能应该查看编译器命令行选项。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-10-09
        • 2011-02-11
        • 2011-03-23
        • 2023-03-10
        • 2011-03-07
        • 2019-03-24
        相关资源
        最近更新 更多