【问题标题】:How does a compiler decide whether it's worth making my functions inline or not?编译器如何决定是否值得让我的函数内联?
【发布时间】:2011-10-06 08:29:28
【问题描述】:

我想知道是否有人知道 C++ 编译器通常用于决定是否在编译时内联函数的逻辑(假设已请求内联)。

这种事情是公开的吗?

【问题讨论】:

  • 如果您有特定的编译器,可能值得一提,因为您可以使用一些标志来影响编译器的决策。
  • 对于微软编译器:stackoverflow.com/questions/1204975/…
  • 您是否请求内联并不是更重要的因素之一。
  • @AlanStokes:确实,C++ 中的inline 关键字主要用于将链接更改为weak,以避免在定义简单时在链接时出现重复符号错误标题中的功能。当然,这些函数也可能会被内联,但问题是(令人惊讶的)正交的。

标签: c++ compiler-construction


【解决方案1】:

我给了更彻底的答案in this other question

基本上,编译器有基于成本分析的启发式方法,引用我自己的话(这是否意味着我会衰老?)

如果您考虑内联及其后果,您就会意识到:

  • 避免函数调用(所有寄存器保存/帧调整)
  • 您向优化器公开了更多上下文(死存储、死代码、公共子表达式消除...)
  • 以复制代码为代价(增加指令缓存和可执行文件大小等)

当然,还有部分内联,其中只有部分函数是内联的,通常是前导 if 保护,如 foo(T* t) { if (!t) { return; } <many many things> }

【讨论】:

  • 谢谢,接受,因为链接的答案非常有帮助:)
【解决方案2】:

是的,这种信息是公共知识。特别是因为那里有大量的开源编译器。

我相信要阅读的书是Dragon Book。他们在那里经历了所有这些,不是吗?

但基本上:函数调用是有代价的——设置寄存器、跳转、收集结果。这可以按周期计算。函数体也有一个以周期衡量的成本。比较两者。考虑缓存局部性的额外积分。

【讨论】:

  • 成本指标中的另一个参数是内联对可执行文件大小的影响。这在嵌入式系统领域尤为重要。
  • 谢谢大家,我喜欢考虑时钟周期方面的成本。
  • 但正如其他人指出的那样,还有其他术语可以考虑成本。例如,空间。
【解决方案3】:

我认为编译器使用某种启发式方法来决定是否内联函数。

如果只从一个地方调用函数,内联它可能会减少一些指令和周期,从而提高大小和速度。

如果它是一个很小的函数,内联也可以做到。

如果函数在紧密循环中被多次调用,内联可以提高性能。

同时内联会导致整体代码更大,并且由于缓存更多代码,还可能对性能产生一些负面影响。

编译器试图做出最佳选择,但他们也必须考虑诸如可配置的优化选项(程序员可能会说他更喜欢速度而不是大小或相反)以及需要多长时间才能完成做出这些决定并生成代码(您不希望编译器大量优化所有内容并花费许多额外的小时或天来编译您的代码)。需要权衡取舍。

另外,编译器也不是万能的。他们只是不能把某些两两放在一起,不是因为那很贵,而是因为这几乎是不可能的。这就是我们进行性能和负载测试、使用分析器并让人类编写代码的原因,因为人类通常仍然比他们的程序更聪明。

【讨论】:

  • 你应该试着写一些段落......关于 call only once 声明,是的,这绝对是一个因素。然而,即使是调用一次的static 函数也可能不会被内联。内联它可能会增加寄存器的压力。
  • @MatthieuM.:为了便于阅读,做了几段,谢谢。
【解决方案4】:

启发式方法将取决于您传递给编译器的选项,并且 也将取决于编译器。没有普遍的答案。最多 当今的编译器具有将内联的选项组合 没有。大多数还具有内联选项的组合 将取决于程序早期运行的分析器输出。 否则:从实施质量的角度来看,它是 合理地期望编译器内联声明 inline 的函数 比那些未声明inline 更积极。它通常会 只有当最激进的优化被激活时 他们将内联一个函数,其定义不存在于 翻译单元。最后,函数中的某些东西可能会抑制 内联:一些编译器可能不会内联递归函数,因为 示例(尽管 g++ 确实如此,至少在某些情况下如此)。

【讨论】:

    猜你喜欢
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-23
    • 2011-06-28
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    相关资源
    最近更新 更多