如何强制gcc内联函数?

Hal*_*ate 57 gcc inline compiler-flags

是否__attribute__((always_inline))强制函数由gcc内联?

RCE*_*RCE 42

是.

文档

always_inline

通常,除非指定了优化,否则不会内联函数.对于内联声明的函数,即使未指定优化级别,此属性也会内联函数.


小智 30

这应该.我是手动内联的忠实粉丝.当然,过度使用它是一件坏事.但通常在优化代码时,会有一两个功能只需要内联或性能下降.坦率地说,根据我的经验,C编译器在使用inline关键字时通常不会内联这些函数.

我非常愿意让编译器为我编写大部分代码.这只是我真正关心的六个左右绝对重要的案例.人们说"编译器在这方面做得很好".我想看看那个证据.到目前为止,我从未见过C编译器在不使用某种强制内联语法(在gcc __forceinline上的msvc __attribute__((always_inline))上)的情况下内联一个重要的代码片段.

  • 我同意但是我更强调内联方式.我在数千个函数上使用了__forceinline,并节省了600个服务器场的20%.假设编译器将做出最佳决策,WRT内联根本就不是真的.编译器正在猜测.不管是否接受过教育,这仍然是猜测.编译器不知道你编写了函数来优化用常量参数形成的表达式.等等 (7认同)
  • 我很欣赏msvc与gcc的比较! (4认同)
  • 使用 gcc,你还需要明确指定 `inline`:`__attribute__((always_inline)) inline YourFunc(...` 否则你会得到 `warning: always_inline 函数可能无法内联 [-Wattributes]` (4认同)

jmk*_*yes 24

是的,它会的.这并不意味着这是一个好主意.

  • 我有时使用它的一个很好的理由示例:在开发音频DSP应用程序时,有时调试版本的处理速度不够快,无法跟上采样率.通过强制访问器函数内联等内容,我可以进行测试和调试. (9认同)
  • 更正:它不是_必然意味着它是一个好主意.有时它是. (3认同)

Bas*_*tch 11

根据gcc优化选项文档,您可以使用参数调整内联:

-finline-limit=n
By default, GCC limits the size of functions that can be inlined. This flag 
allows coarse control of this limit. n is the size of functions that can be 
inlined in number of  pseudo instructions.

Inlining is actually controlled by a number of parameters, which may be specified
individually by using --param name=value. The -finline-limit=n option sets some 
of these parameters as follows:

    max-inline-insns-single is set to n/2. 
    max-inline-insns-auto is set to n/2.
Run Code Online (Sandbox Code Playgroud)

我建议详细阅读有关内联的所有参数的详细信息,并进行适当的设置.


Red*_*rav 6

我想在这里补充一点,我有一个 SIMD 数学库,其中内联对于性能绝对至关重要。最初,我将所有函数设置为内联,但反汇编表明,即使对于最简单的运算符,它也会决定实际调用该函数。MSVC 和 Clang 都显示了这一点,并且所有优化标志都打开。

我按照 SO 中其他帖子中的建议进行操作,并__forceinline为 MSVC 和__attribute__((always_inline))所有其他编译器添加了内容。从基本乘法到正弦运算,各种紧密循环的性能持续提高了 25-35%。

我不明白为什么他们内联如此困难(也许模板化代码更难?),但底线是:手动内联有非常有效的用例,并且可以获得巨大的加速。

如果你好奇的话,这就是我实现它的地方。https://github.com/redorav/hlslpp

  • 模板函数代码往往不会内联,而是每个专业化都会进入一个单独的“.text”部分,以便使“模糊链接”成为可能(请参阅https://gcc.gnu.org/onlinedocs/gcc-4.8.0 /gcc/Vague-Linkage.html)。通过强制内联,您基本上失去了在不同编译单元中显式专门化模板函数的能力。 (2认同)

Mat*_*ner 5

是的。无论设置任何其他选项,它都会内联该函数。看这里