I have a function which operates on piece of data (let's say, an int
), and I want to change it in place by passing a reference to the valule. As such, I have the function: void myFunction(int *thing) { ... }
. When I use it I call it thus: myFunction(&anInt)
.
As my function is called frequently (but from many different places) I am concerned about its performance. The reason I have refactored it into a function is testability and code reuse.
Will the compiler be able to optimize the function, inlining it to operate directly on my anInt
variable?
I hope you'll take this question in the spirit in which it's asked (i.e. I'm not prematurely worrying about optimisation, I'm curious about the answer). Similarly, I don't want to make it into a macro.
GCC automatically inlines member functions defined within the class body of C++ programs even if they are not explicitly declared inline .
Inline function expansion can speed up execution by eliminating function call overhead. This is particularly beneficial for very small functions that are called frequently. Function inlining involves a tradeoff between execution speed and code size, because the code is duplicated at each function call site.
The __inline keyword suggests to the compiler that it compiles a C or C++ function inline, if it is sensible to do so. The semantics of __inline are exactly the same as those of the inline keyword. However, inline is not available in C90. __inline is a storage class qualifier.
The linker can inline small functions in place of a branch instruction to that function. For the linker to be able to do this, the function (without the return instruction) must fit in the four bytes of the branch instruction.
One way to find out if the function is inlined is to use -Winline
gcc option:
-Winline Warn if a function can not be inlined and it was declared as inline. Even with this option, the compiler will not warn about failures to inline functions declared in system headers. The compiler uses a variety of heuristics to determine whether or not to inline a function. For example, the compiler takes into account the size of the function being inlined and the amount of inlining that has already been done in the current function. Therefore, seemingly insignificant changes in the source program can cause the warnings produced by -Winline to appear or disappear.
GCC is quite smart. Consider this code fragment:
#include <stdio.h>
void __inline__ inc(int *val)
{
++ *val;
}
int main()
{
int val;
scanf("%d", &val);
inc(&val);
printf("%d\n", val);
return 0;
}
After a gcc -S -O3 test.c
you'll get the following relevant asm:
...
call __isoc99_scanf
movl 12(%rsp), %esi
movl $.LC1, %edi
xorl %eax, %eax
addl $1, %esi
movl %esi, 12(%rsp)
call printf
...
As you can see, there's no need to be an asm expert to see the inc() call has been converted to an increment instruction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With