【问题标题】:C compiler optimisation(gcc): Automatically Inline a non-static function vs static functionC 编译器优化(gcc):自动内联非静态函数与静态函数
【发布时间】:2016-11-24 05:20:48
【问题描述】:

我看到 GCC 编译器在使用优化级别 3 时会内联静态函数,但在一种情况下不会内联非静态函数。而在其他情况下,它内联函数,无论是静态的还是非静态的。 我想知道静态或非静态函数将选择哪些参数进行内联。

【问题讨论】:

  • 我很确定您在 GCC 的源代码之外找不到完整的列表。当然,这可能因版本而异,因编译器而异。但是,该标准包含一些限制。
  • 如果静态函数的地址从不返回,则可以内联它,因为编译器知道如何使用它。非静态函数不一定是内联的,因为其他源文件中的代码可能会调用它。或者,至少,必须定义非内联函数,以便可以从其他翻译单元调用它,即使本地使用是内联的。

标签: c gcc static


【解决方案1】:

来自 gcc 的手册:

-O3 优化更多。 -O3 开启 -O2 指定的所有优化,同时开启 -finline-functions, -funswitch-loops,-fpredictive-commoning,-fgcse-after-reload,-ftree-loop-vectorize,-ftree-loop-distribute-patterns, -fsplit-paths -ftree-slp-vectorize、-fvect-cost-model、-ftree-partial-pre 和 -fipa-cp-clone 选项。

您的评论似乎来自 -finline-functions 选项:

-finline-functions

考虑所有的内联函数,即使它们没有被声明为内联。编译器启发式地决定哪个 功能值得以这种方式集成。

如果对给定函数的所有调用都被集成,并且该函数被声明为“静态”,那么该函数通常是 本身不作为汇编代码输出。

在 -O3 级启用。

事实上,所有函数都受制于 gcc 在 -O3 优化模式下的内联,无论是声明为内联、静态,还是两者都不声明。

这是 gcc 的另一部分手册页(-Winline 选项):

编译器使用各种启发式方法来确定是否内联函数。例如,编译器 考虑到被内联函数的大小和已经完成的内联数量 当前函数。

所以 gcc 使用函数的大小和函数中内联的数量来选择是否内联。如果您想了解更多关于这些启发式的信息,恐怕您可能需要查看 gcc 的源代码 :)

【讨论】:

  • 这里重要的启发式是针对static 单调用函数,并且是所有体面的优化 C 编译器。内联实际上是大小与速度的权衡,但如果由于非内联版本无法访问而实际上没有任何损失,则可能会被丢弃。自然会有皱纹和特殊情况,但这是一般的想法。
  • @doynax 启发式不仅适用于static;不同之处在于,该函数可以完全从汇编代码和符号表中省略。
  • 程序员的重要信息:今天,不需要#defineing 具有多重评估、优先级和分号的“优化”类函数宏(例如,max(a,b))问题。 (如果您需要访问编译时宏,例如 __LINE____FILE__(参见 assert())或需要符号连接或字符串化(例如用于变量/代码生成),它们仍然很有用。
猜你喜欢
  • 2016-12-09
  • 2011-07-18
  • 1970-01-01
  • 1970-01-01
  • 2021-10-20
  • 1970-01-01
  • 2016-11-05
相关资源
最近更新 更多