Reputation: 13748
When I inspect other people's codes, I sometimes encounter static inline functions implemented in header files as opposed to regular function implementations in C files.
For example, cache.h
header file (https://github.com/git/git/blob/master/cache.h) of git
contains many such functions. One of them is copied below;
static inline void copy_cache_entry(struct cache_entry *dst,
const struct cache_entry *src)
{
unsigned int state = dst->ce_flags & CE_HASHED;
/* Don't copy hash chain and name */
memcpy(&dst->ce_stat_data, &src->ce_stat_data,
offsetof(struct cache_entry, name) -
offsetof(struct cache_entry, ce_stat_data));
/* Restore the hash state */
dst->ce_flags = (dst->ce_flags & ~CE_HASHED) | state;
}
I was wondering what are the advantages of using static inline functions compared to regular functions. Is there any guideline one can use to choose which style to adapt?
Upvotes: 3
Views: 5583
Reputation: 1
static inline
functions are especially safe to use in microcontrollers. These devices often do not have an instruction cache (check datasheet) and thus inlining is always saving time.
Upvotes: 0
Reputation: 40625
Inlining is done for optimization. However, a little known fact is that inline
can also hurt performance: Your CPU has an instruction cache with a fixed size, and inlining has the downside of replicating the function at several places, which makes the instruction cache less efficient.
So, from a performance point of view, it's generally not advisable to declare functions inline
unless they are so short that their call is more expensive than their execution.
To put this in relation: a function call takes somewhere between 10 to 30 cycles of CPU time (depending on the amount of arguments). Arithmetic operations generally take a single cycle, however, memory loads from first level cache takes something like three to four cycles. So, if your function is more complex than a simple sequence of at most three memory accesses and some arithmetic, there is little point in inlining it.
I usually take this approach:
If a function is as simple as incrementing a single counter, and if it is used all over the place, I inline it. Examples of this are rare, but one valid case is reference counting.
If a function is used only within a single file, I declare it as static
, not inline
. This has the effect that the compiler can see when such a function is used precisely one time. And if it sees that, it will very likely inline it, no matter how complex it is, since it can prove that there is no downside of inlining.
All other functions are neither static
nor inline
.
The example in your question is a borderline example: It contains a function call, thus it seems to be too complex for inlining at first sight.
However, the memcpy()
function is special: it is seen more as a part of the language than as a library function. Most compilers will inline it, and optimize it heavily when the size is a small compile time constant, which is the case in the code in question.
With that optimization, the function is indeed reduced to a short, simple sequence. I cannot say whether it touches a lot of memory because I don't know the structure that is copied. If that structure is small, adding the inline
keyword seems to be a good idea in this case.
Upvotes: 10
Reputation: 5543
The potential advantage of inlining is, that a function call can be avoided, which may save some execution time and stack memory, sacrificing some space for the executable (if the function is used more than once). It may also allow further optimizations by eliminating dead code (e.g. a function returning an error code for an invalid argument, calling a function doing the same checks, where the second identical check can be removed when inlined). Note, that inlining as an optimization technique and an inline definition (as defined by the C standard) are two different thins: A compiler may inline every function where it sees a definition, and may decide to perform an actual function call for an inline
function.
Every function declared static
in a strictly conforming program can be declared inline
. This is only a hint for the compiler and doesn't have any semantic meaning (nb, for functions with external linkage, there is a difference).
Sometimes, static inline
is seen as a type-checking alternative for a macro function and thus could be seen as serving some documentation purposes.
It's important to document a function as being static
and defined in the header (or at least as being potentially static
and defined in the header), as the user of such a header must not assume that taking the address of the function in different translation units yields equal results.
If a definition should be in a header (to allow inlining), I personally prefer inline functions with external linkage, as addresses compare equal and the compiler still can inline if it thinks it's worth it.
Upvotes: 0
Reputation: 42838
inline
allows you to define functions in a header.
static
makes the function available only in the current translation unit.
Upvotes: 2
Reputation: 500407
The main reason is performance: when used appropriately, inline functions could enable the compiler to generate more efficient code.
A good strategy for identifying performance bottlenecks is to profile the code. Once that's done, the most effective way to improve performance is by focusing on the bottlenecks. There are many strategies, such as algorithmic improvements, etc. One such strategy is make short frequently-used function inline.
Like with any other attempts to improve performance, the result needs to be tested to ensure that the change was actually beneficial.
Upvotes: 1