Can I selectively (force) inline a function?
Asked Answered
G

9

37

In the book Clean Code (and a couple of others I have come across and read) it is suggested to keep the functions small and break them up if they become large. It also suggests that functions should do one thing and one thing only.

In Optimizing software in C++ Agner Fog states that he does not like the rule of breaking up a function just because it crosses a certain threshold of a number of lines. He states that this results in unnecessary jumps which degrade performance.

First off, I understand that it will not matter if the code I am working on is not in a tight loop and that the functions are heavy so that the time it takes to call them is dwarfed by the time the code in the function takes to execute. But let's assume that I am working with functions that are, most of the time, used by other objects/functions and are performing relatively trivial tasks. These functions follow the suggestions listed in the first paragraph (that is, perform one single function and are small/comprehensible). Then I start programming a performance critical function that utilizes these other functions in a tight loop and is essentially a frame function. Lastly, assume that in-lining them has a benefit for the performance critical function but no benefit whatsoever to any other function (yes, I have profiled this, albeit with a lot of copying and pasting which I want to avoid).

Immediately, one can say that tag the function inline and let the compiler choose. But what if I don't want all those functions to be in a `.inl file or exposed in the header? In my current situation, the performance critical functions and the other functions it uses are all in the same source file.

To sum it up, can I selectively (force) inline a function(s) for a single function so that the end code behaves like it is one big function instead of several calls to other functions.

Garderobe answered 18/8, 2011 at 14:12 Comment(4)
Unless you are using the preprocessor, which isn't the same thing at all, anything you do to indicate that a function should be inlined can be ignored by the compilier.Similitude
gcc offers the -Winline option to warn you about functions that have been marked inline but weren't. This is a start but no solution to your problem.Nosology
Since the functions are all in the right source file, and aren't used elsewhere, I'd say just mark them static inline and let the compiler get on with it. If it thinks that it will produce better code by not inlining them, who knows, maybe it's right. Were you to specify a compiler, people could suggest any options that it has to force inlining, but since you seem to want a portable solution, it's "let the compiler optimize, it knows more about the platform than you do, since you know precisely nothing about the platform".Carminecarmita
I think there should be a way to do it. I create my version of a function of one STL algorithm and the compiler GCC, and clang, don't inline the function and It takes 10x more of time than STL, and when I paste the function inside it takes just 0.9X. So yeah! sometimes is necessary to force inline.Barton
S
17

You cannot force the inline. Also, function calls are pretty cheap on modern CPUs, compared to the cost of the work done. If your functions are large enough to need to be broken down, the additional time taken to do the call will be essentially nothing.

Failing that, you could ... try ... to use a macro.

Sequestered answered 18/8, 2011 at 14:18 Comment(5)
I changed my style to match the suggestions by writers of various books (that I am sure know better than me) by writing functions so that they do what their name suggests and nothing more and to keep the function vertical length small. This resulted in a lot of smaller functions which had a performance impact on my most recent performance sensitive code. After reading Agner Fog's book, I started thinking of the other aspect and am wondering whether I should strike a balance between the two contrasting pieces of advice (selective inline would have been the ideal solution - and macro may be it)Garderobe
Now you can use __forceinline (msdn.microsoft.com/en-us/bw1hbe6y)Attaway
_forceinline instructs the compiler to do its best to inline a function without performing any cost/benefit analysis. learn.microsoft.com/en-us/cpp/cpp/…Palatinate
This is now outdated please see some of the other answers below.Canzonet
Adding __attribute__((always_inline)) to my inline functions made my library 36% faster so it is beneficial.Newsmonger
T
21

There is nothing that prevents you to put inline in a static function in a .cpp file.

Some compilers have the option to force an inline function, see e.g. the GCC __attribute__((always_inline)) and a ton of options to fine tune the inlining optimizations (see -minline-* parameters).

My recommendation is to use inline or even better static inline wherever you see fit, and let the compiler decide. They usually do it pretty well.

Theotokos answered 18/8, 2011 at 14:21 Comment(2)
That is a good suggestion. It does not work in my particular situation but definitely something to keep in mind (+1).Garderobe
In some, mostly embedded, projects, the need of logical separation but "physical" contiguity of code often emerges. Consider interrupt handler routines, for example, where a number of mandatory operations must be performed both in the beginning and in the end. These operations may be implemented perfectly as static inline functions as long as it is guaranteed that the interrupt routine won't be polluted with extra stack pottering and call instructions (i.e the function is really inlined).Undulant
S
17

You cannot force the inline. Also, function calls are pretty cheap on modern CPUs, compared to the cost of the work done. If your functions are large enough to need to be broken down, the additional time taken to do the call will be essentially nothing.

Failing that, you could ... try ... to use a macro.

Sequestered answered 18/8, 2011 at 14:18 Comment(5)
I changed my style to match the suggestions by writers of various books (that I am sure know better than me) by writing functions so that they do what their name suggests and nothing more and to keep the function vertical length small. This resulted in a lot of smaller functions which had a performance impact on my most recent performance sensitive code. After reading Agner Fog's book, I started thinking of the other aspect and am wondering whether I should strike a balance between the two contrasting pieces of advice (selective inline would have been the ideal solution - and macro may be it)Garderobe
Now you can use __forceinline (msdn.microsoft.com/en-us/bw1hbe6y)Attaway
_forceinline instructs the compiler to do its best to inline a function without performing any cost/benefit analysis. learn.microsoft.com/en-us/cpp/cpp/…Palatinate
This is now outdated please see some of the other answers below.Canzonet
Adding __attribute__((always_inline)) to my inline functions made my library 36% faster so it is beneficial.Newsmonger
R
12

No, inline is a recommendation to the compiler ; it does not force it to do anything. Also, if you're working with MSVC++, note that __forceinline is a misnomer as well ; it's just a stronger recommendation than inline.

Rowan answered 18/8, 2011 at 14:16 Comment(5)
That I understand. The compiler is not able to inline some functions no matter what but it will not consider its own analysis when __forceinline is used and the function will be inlined if it can be.Garderobe
@Samaursa: Yes, but the whole point is that you can never assume that the function will be inlined with any variant of the inline keyword (as per your question). At the most, you may be able to increase the chance of it being inlined.Rowan
@Jacob: You can't assume it, but you can verify it through enabling all warnings with /Wall and noting which functions weren't inlined.Antithesis
@Rowan Indeed, I doubted it but you are right, "You cannot force the compiler to inline a particular function, even with the __forceinline keyword."Hedger
A ton of info here: learn.microsoft.com/en-us/cpp/cpp/…Palatinate
P
11

This is as much about good old fashioned straight C as it is about C++. I was pondering this the other day, because in an embedded world, where both speed and space need to be carefully managed, this can really matter (as opposed to the all too oft "don't worry about it, your compiler is smart and memory is cheap prevalent in desktop/server development).

A possible solution that I have yet to vet is to basically use two names for the different variants, something like

inline int _max(int a, int b) {
    return a > b ? a : b;
}

and then

int max(int a, int b) {
    return _max(a, b);
}

This would give one the ability to selectively call either _max() or max() and yet still having the algorithm defined once-and-only-once.

Puduns answered 28/11, 2012 at 18:58 Comment(0)
D
4

If you have a known-hot function an want the compiler inline more aggressively than usual the flatten attribute offered by gcc/clang might be something to look into. In contrast to the inline keyword and attributes it applies to inlining decisions regarding the functions called in the marked function.

__attribute__((flatten)) void hot_code() {
    // functions called here will be inlined if possible
}

See https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html and https://clang.llvm.org/docs/AttributeReference.html#flatten for official documentation.

Denitrify answered 30/5, 2021 at 13:26 Comment(0)
T
2

Inlining – For example, if there exists a function A that frequently calls function B, and function B is relatively small, then profile-guided optimizations will inline function B in function A.

VS Profile-Guided Optimizations

You can use the automated Profile Guided Optimization for Visual C++ plug-in in the Performance and Diagnostics Hub to simplify and streamline the optimization process within Visual Studio, or you can perform the optimization steps manually in Visual Studio or on the command line. We recommend the plug-in because it is easier to use. For information on how to get the plug-in and use it to optimize your app, see Profile Guided Optimization Plug-In.

Tweeny answered 28/2, 2017 at 21:54 Comment(0)
T
1

Compilers are actually really really good at generating optimized code.

I would suggest just organizing your code into logical groupings (using additional functions if that enhanced readability), marking them inline if appropriate, and letting the compiler decide what code to optimally generate.

Tetrafluoroethylene answered 18/8, 2011 at 14:23 Comment(1)
Not appliable in some cases: sometimes, inline is used as an alternative to macros, since they are debuggable, more readable and can be put into a namespace. Sometimes, stack frame allocation can build up into precious microseconds of delay, and compiler might not know the execution frequency without the context (what if you inline a sin() function and the compiler does not inline it for some reason?).Ilailaire
C
1

Quite surprised this hasn't been mention yet but as of now you can tell the compiler (I believe it may only work with GCC/G++) to force inline a function and ignore a couple restrictions associated with it.

You can do so via __attribute__((always_inline)).

Example of it in use:

inline __attribute__((always_inline)) int pleaseInlineThis() {
   return 5;
}

Normally you should avoid forcing an inline as the compiler knows what's best better than you; however there are several use cases such as in OS/MicroController development where you need to inline calls where if it is instead called, would break the functionality.

C++ compilers usually aren't very friendly to controlled environments such as those without some hacks.

Canzonet answered 31/8, 2021 at 15:48 Comment(0)
U
0

As people mentioned, you should avoid doing that as the compiler usually makes better decisions. There are several optimizations that you can enable to improve performance. These will inline the functions if needed:

  • LTO: link-time optimization or interprocedural optimization
  • Profile guided optimization: optimizations based on a runtime profile
  • BOLT: Binary Optimization and Layout Tool
  • Polly: a high-level loop and data-locality optimizer
Underclothing answered 28/4, 2022 at 20:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.