Bots, Bureaucrats, Interface administrators, smwadministrator, smwcurator, smweditor, Administrators
2,557
edits
Timo.stripf (talk | contribs) No edit summary |
Timo.stripf (talk | contribs) No edit summary |
||
Line 11: | Line 11: | ||
<ref name="Fabien"/> ''Inline expansion removes overhead.'' After inlining, the function’s code is substituted at the call site, so the call and its prologue/epilogue overhead are removed (the red overhead boxes are gone). The program continues executing the inlined body as if it were part of the caller. | <ref name="Fabien"/> ''Inline expansion removes overhead.'' After inlining, the function’s code is substituted at the call site, so the call and its prologue/epilogue overhead are removed (the red overhead boxes are gone). The program continues executing the inlined body as if it were part of the caller. | ||
Because the function body is now part of the caller, the compiler can optimize across what was once a call boundary. For example, if certain arguments are constants at the call site, those constant values may propagate into the inlined function, allowing the compiler to simplify calculations or remove branches inside the function <ref>Inline - Using the GNU Compiler Collection (GCC) https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Inline.html</ref>. In effect, inlining can make two separate functions behave as one larger function, which often enables additional compiler optimizations that would not be possible otherwise. | Because the function body is now part of the caller, the compiler can optimize across what was once a call boundary. For example, if certain arguments are constants at the call site, those constant values may propagate into the inlined function, allowing the compiler to simplify calculations or remove branches inside the function <ref ame="gcc">Inline - Using the GNU Compiler Collection (GCC) https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Inline.html</ref>. In effect, inlining can make two separate functions behave as one larger function, which often enables additional compiler optimizations that would not be possible otherwise. | ||
== Advantages and Disadvantages == | == Advantages and Disadvantages == | ||
Line 17: | Line 17: | ||
'''Advantages:''' | '''Advantages:''' | ||
* '''Eliminating call overhead:''' Inlining avoids the runtime cost of pushing function arguments, jumping to the function, and returning from it. This can make execution faster, especially for very small or frequently called functions where the call overhead is a significant portion of the runtime cost. | * '''Eliminating call overhead:''' Inlining avoids the runtime cost of pushing function arguments, jumping to the function, and returning from it. This can make execution faster, especially for very small or frequently called functions where the call overhead is a significant portion of the runtime cost. | ||
* '''Enabling further optimizations:''' By merging the function code into the caller, the compiler gains a wider scope for optimization. It can perform constant propagation, common subexpression elimination, loop optimizations, and other transformations across what used to be a function boundary <ref | * '''Enabling further optimizations:''' By merging the function code into the caller, the compiler gains a wider scope for optimization. It can perform constant propagation, common subexpression elimination, loop optimizations, and other transformations across what used to be a function boundary <ref name="gcc"/>. For instance, inlined code might expose that a condition is always true in a particular context, allowing dead code elimination in the combined code. | ||
* '''Potentially improved performance and smaller code for tiny functions:''' If a function is very simple (e.g., just returns a calculation or a field) and is called often, inlining it might not only speed up execution but could ''reduce'' code size by removing the call/return sequence. (In some cases, the overhead of a call is larger than the function body itself.) Inlining such small functions can both save time and avoid duplicate function call setup code, yielding faster and ''sometimes'' smaller binaries <ref | * '''Potentially improved performance and smaller code for tiny functions:''' If a function is very simple (e.g., just returns a calculation or a field) and is called often, inlining it might not only speed up execution but could ''reduce'' code size by removing the call/return sequence. (In some cases, the overhead of a call is larger than the function body itself.) Inlining such small functions can both save time and avoid duplicate function call setup code, yielding faster and ''sometimes'' smaller binaries <ref name="gcc"/>. | ||
* '''Better use of instruction pipeline:''' Eliminating function calls can help the CPU’s instruction pipeline and branch predictor. With no branch to an external function, there’s no risk of misprediction or pipeline flush for that call, which can improve the instruction flow continuity (though this benefit is context-dependent). | * '''Better use of instruction pipeline:''' Eliminating function calls can help the CPU’s instruction pipeline and branch predictor. With no branch to an external function, there’s no risk of misprediction or pipeline flush for that call, which can improve the instruction flow continuity (though this benefit is context-dependent). | ||
Line 36: | Line 36: | ||
=== GCC (GNU Compiler Collection) === | === GCC (GNU Compiler Collection) === | ||
In GCC, the <code>inline</code> keyword in C and C++ is a hint that the function’s code should be integrated into callers to avoid call overhead <ref | In GCC, the <code>inline</code> keyword in C and C++ is a hint that the function’s code should be integrated into callers to avoid call overhead <ref name="gcc"/>. For example, writing <code>inline int f(int x) { return x*2; }</code> suggests to the compiler that calls to <code>f</code> can be replaced with <code>x*2</code> directly. In practice, GCC will consider inlining such functions when optimization is enabled, but '''will not inline at all under <code>-O0</code> (no optimizations)''' unless explicitly forced <ref name="gcc"/>. At higher optimization levels (<code>-O2</code>, <code>-O3</code>), GCC’s optimizer will inline functions it deems suitable. | ||
By default, GCC applies some inlining at <code>-O2</code> for functions marked <code>inline</code> (and certain trivial functions), and becomes more aggressive at <code>-O3</code>. In fact, the flag <code>-finline-functions</code> (enabled as part of <code>-O3</code>) tells GCC to attempt inlining of ''any'' “simple enough” functions, even those not marked with the <code>inline</code> keyword <ref | By default, GCC applies some inlining at <code>-O2</code> for functions marked <code>inline</code> (and certain trivial functions), and becomes more aggressive at <code>-O3</code>. In fact, the flag <code>-finline-functions</code> (enabled as part of <code>-O3</code>) tells GCC to attempt inlining of ''any'' “simple enough” functions, even those not marked with the <code>inline</code> keyword <ref name="gcc"/>. This means at <code>-O3</code> the compiler will use its heuristics to inline more liberally across the codebase, within limits designed to control code bloat. (These limits can be tweaked via internal parameters like the maximum permitted inline instruction growth <ref>Optimize Options (Using the GNU Compiler Collection (GCC)) https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html</ref>, but such tuning is rarely needed.) The result is that <code>-O3</code> can inline many small or medium-sized functions automatically, while <code>-O2</code> is more conservative (focusing mostly on functions that are explicitly declared inline or very small). | ||
GCC also provides the '''<code>always_inline</code> attribute''' to force inlining. A function declared with <code>__attribute__((always_inline))</code> (and usually also marked <code>inline</code>) will be inlined regardless of the compiler’s normal heuristics '''and even if optimizations are off''' <ref>Function Attributes - Using the GNU Compiler Collection (GCC) https://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Function-Attributes.html</ref>. In other words, this attribute directs GCC to bypass any cost-benefit analysis for that function. According to GCC’s documentation and source, <code>always_inline</code> causes the compiler to ignore even commands like <code>-fno-inline</code> and to inline the function without regard to size limits (it will even inline functions using constructs like alloca, which ordinary inlining might not allow) <ref>c - what “inline '''attribute'''((always_inline))” means in the function? - Stack Overflow https://stackoverflow.com/questions/22767523/what-inline-attribute-always-inline-means-in-the-function</ref>. This attribute is useful for cases where the programmer is certain that inlining is critical (for example, a performance-sensitive function that must not have call overhead, or functions that must be inlined for correctness in some low-level code). However, misuse of <code>always_inline</code> can lead to the aforementioned problems of code bloat and cache issues if applied indiscriminately. (If for some reason the compiler cannot inline a function marked <code>always_inline</code> – e.g., a recursive call or other unavoidable situation – GCC will emit an error or warning, since it '''must''' honor the attribute’s contract.) | GCC also provides the '''<code>always_inline</code> attribute''' to force inlining. A function declared with <code>__attribute__((always_inline))</code> (and usually also marked <code>inline</code>) will be inlined regardless of the compiler’s normal heuristics '''and even if optimizations are off''' <ref>Function Attributes - Using the GNU Compiler Collection (GCC) https://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Function-Attributes.html</ref>. In other words, this attribute directs GCC to bypass any cost-benefit analysis for that function. According to GCC’s documentation and source, <code>always_inline</code> causes the compiler to ignore even commands like <code>-fno-inline</code> and to inline the function without regard to size limits (it will even inline functions using constructs like alloca, which ordinary inlining might not allow) <ref>c - what “inline '''attribute'''((always_inline))” means in the function? - Stack Overflow https://stackoverflow.com/questions/22767523/what-inline-attribute-always-inline-means-in-the-function</ref>. This attribute is useful for cases where the programmer is certain that inlining is critical (for example, a performance-sensitive function that must not have call overhead, or functions that must be inlined for correctness in some low-level code). However, misuse of <code>always_inline</code> can lead to the aforementioned problems of code bloat and cache issues if applied indiscriminately. (If for some reason the compiler cannot inline a function marked <code>always_inline</code> – e.g., a recursive call or other unavoidable situation – GCC will emit an error or warning, since it '''must''' honor the attribute’s contract.) | ||
It’s worth noting that in C++ programs, GCC automatically treats any function defined ''inside a class definition'' as inline (this is mandated by the C++ standard). GCC will attempt to inline such functions even without the <code>inline</code> keyword <ref | It’s worth noting that in C++ programs, GCC automatically treats any function defined ''inside a class definition'' as inline (this is mandated by the C++ standard). GCC will attempt to inline such functions even without the <code>inline</code> keyword <ref name="gcc"/>. Also, if a function is declared <code>inline</code>, GCC still emits a standalone function definition for it ''unless'' it can prove that every call was inlined and no external reference is needed. This means an inline function might not actually be inlined everywhere, but the one-definition rule is respected by outputting one copy if needed (you can prevent outputting unused inline functions with the <code>-fkeep-inline-functions</code> flag, for instance <ref name="gcc"/>). | ||
'''Summary (GCC):''' Use the <code>inline</code> keyword to hint inlining, and the <code>__attribute__((always_inline))</code> to strongly force it (typically combined with <code>inline</code> in the definition). At <code>-O3</code> or with <code>-finline-functions</code>, GCC becomes more aggressive about inlining automatically. The compiler will ignore inline hints for overly large functions or if other constraints prevent inlining. | '''Summary (GCC):''' Use the <code>inline</code> keyword to hint inlining, and the <code>__attribute__((always_inline))</code> to strongly force it (typically combined with <code>inline</code> in the definition). At <code>-O3</code> or with <code>-finline-functions</code>, GCC becomes more aggressive about inlining automatically. The compiler will ignore inline hints for overly large functions or if other constraints prevent inlining. |
edits