【问题标题】:Is link time optimization in gcc 5.1 good enough to give up on inlining simple functions?gcc 5.1 中的链接时间优化是否足以放弃内联简单函数?
【发布时间】:2015-04-23 22:32:06
【问题描述】:

出于习惯,我经常为像这样的简单函数内联编写函数定义(人为的例子)

class PositiveInteger
{
private:
    long long unsigned m_i;
public:
    PositiveInteger (int i);
};

inline PositiveInteger :: PositiveInteger (int i)
: m_i (i)
{
    if (i < 0)
        throw "oops";
}

我通常喜欢将接口文件和实现文件分开,但这是我的习惯,对于那些我脑海中的声音告诉我的功能可能会在热点中受到很多打击。

我知道建议是“配置文件优先”,我同意,但如果我知道先验编译器会生成相同的最终目标代码,无论像这样的函数,我都可以避免大量的分析工作在编译或链接时内联。 (另外,我相信注入的分析代码本身会导致时序变化,从而淹没非常简单的函数(例如上面的函数)的效果。)

GCC 5.1 刚刚发布,宣传 LTO(链接时间优化)改进。他们真的有多好?知道最终的可执行文件不会受到影响,我可以安全地取消内联哪些类型的函数?

【问题讨论】:

  • 那个代码格式……疼……眼睛。 PositiveInteger::PositiveInteger 是事物的名称。它是合格的,但仍然只是一个名称。为什么要在里面放空格?
  • 我发现你写它的方式让 我的 眼睛很痛,尽管我知道到目前为止它更常见。与将空格放在其他任何地方的论点相同。

标签: c++ gcc


【解决方案1】:

您已经回答了自己的问题:除非您的目标是某种资源受限的嵌入式系统,否则请先编写代码以确保清晰和可维护。然后 如果 性能不可接受,您可以分析并将您的努力定位到实际热点。想一想:如果您编写更清晰的代码需要额外的 250ns,而这在您的用例中并不明显,那么额外的时间并不重要。

【讨论】:

  • 前提是如果编译器不内联它,它发生明显变慢。但是,如果我知道编译器内联它,那么我可以完全停止考虑它。没有分析。
【解决方案2】:

带有 LTO 的 GCC 会进行跨模块内联,因此大多数时候您不会看到代码质量的差异。离线函数声明也不会跨翻译单元重复,编译速度更快/生成更小的目标文件。

GCC 的内联启发式算法将“inline”关键字视为函数可能适合内联并增加对函数大小的限制的提示。同样,对于在与调用相同的翻译单元中声明的函数,它将需要一些额外的提示。但是,对于您示例中的小功能,这应该没有任何区别。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-10
    • 2016-12-09
    • 2011-10-26
    • 1970-01-01
    • 2015-11-20
    • 2011-09-01
    • 2015-07-10
    • 2016-05-23
    相关资源
    最近更新 更多