如何判断编译器内联的内容或内容?
有时我被告知一些小的优化是没有意义的,因为编译器会内联某些调用或计算,其他时候似乎建议采用类似的优化。
有什么规则可以让我们知道什么时候或者不需要优化这些东西?
答案 0 :(得分:2)
查看内联是否内联的唯一可靠方法是查看程序集。
是否内联的内容完全取决于编译器 - 因为编译器最终决定是否内联。
除了过早的优化:如果真的很重要(或者你只是好奇的话),你可以使用特定于编译器的编译指示来强制函数内联/不内联,然后适当地进行配置以查看是否你可以做出比编译器更好的决定。
尽管如此,在某些情况下您可以确定无法内联函数:
答案 1 :(得分:1)
这似乎有些切合,但我认为这很重要。
有什么规则可以让我们知道我们何时需要或不需要 优化这些东西?
我想说在任何其他人之前有两条规则可以发挥作用W.R.T.这个具体问题:
这可能没关系。除非您在Release版本中分析了代码并证明与函数调用相关的开销是代码中的主要瓶颈,否则最好忘记inline
代码的性能影响。
您很少或根本无法控制编译器将不会内联的内容。如果编译器认为合适,可以忽略inline
。有些事情是不可能内联的。有些平台提供force_inline
行的语言扩展,但即便如此也可以忽略。
答案 2 :(得分:0)
答案 3 :(得分:0)
How can you tell what will or what won't be made inline by the compiler?
你不能:)例如,如果你使用inline关键字,它只是一个提示,没有编译器有义务尊重它。但是,如果您需要疯狂的优化,似乎您可能需要在比c / c ++更低的级别编码并使用汇编调用
答案 4 :(得分:0)
你看过SO了吗?
例如:
Does GCC inline C++ functions without the 'inline' keyword?
Why not mark everything inline?
你问的问题非常笼统 - 因为它取决于哪些编译器,更不用说哪个版本了。听起来你正在做的是过早优化 - 你应该分析你的代码并找到减慢它的区域。这种呈现"这是内联的吗?"问题没有实际意义,因为您将关注编译器的后效,包括内联和其他优化。
答案 5 :(得分:0)
没有办法确定,有关详细信息,为什么以及何时内联是一种良好做法,我建议您阅读this C++ FAQ
答案 6 :(得分:0)
您无法知道编译器在优化阶段内联的内容:您应该清楚地了解精确编译器的启发式方法。但是,您可以指定要内联的内容。
答案 7 :(得分:0)
Microsoft的Compiler很长一段时间都有/ Ob优化标志,强制它内联所有显式声明inline
的函数。这是非标准的,默认情况下,它的行为符合标准,即将关键字视为提示。英特尔Parallel Studio编译器的行为类似。
答案 8 :(得分:0)
如何判断编译器内联的内容和内容是什么?
一般来说,你不能。
您可能需要阅读Herb Sutter撰写的Inline Redux文章。它揭示了许多技术来解释何时可能发生内联,知道后者发生了......你拥有的信息越多。
例如,在JIT环境中,你可以查看一个循环,意识到它的整个主体是在一个似乎经常是Foo
类型的对象上执行的,它专门用于{{Foo
。 1}},允许完整内联虚拟方法,现在检查循环的顶部是否对象是Foo
,如果是,则切换到完全内联的正文版本而不是具有虚拟调用的通用版本。
那么可以内联什么?这取决于......
一般来说,C ++编译器的特点是:
这意味着它们只能将其优化基于静态(在编译时已知)信息。
在编译时,这意味着如果静态类型虚拟调用可能被虚拟化(内联的第一步:猜测实际调用的函数;))。这意味着任何定义都可见的函数也可以内联。
在库的链接时,您基本上公开了新的函数定义,允许内联几个调用。
在可执行文件的链接时,WPA(整个程序分析)可以通过意识到某些类永远不会从中派生来启动添加一些虚拟化,因此可以认为final
就此可执行文件而言关心。 GCC和LLVM(我怀疑VC ++都不会)可能会执行此优化,因为它们没有保持类层次结构的字节代码。
如果他们希望,编译器可以转储他们拥有的中间表示(某种方式为字节码)并等待安装以内联OS特定的调用。虽然我知道没有(对于C ++)这样做。
运行时更改在C ++中非常棘手,因为程序员可以访问内存(例如函数地址),因此很难只进行安全转换......