Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are C++ function calls cheap?

Tags:

c++

While reading Stroustrup's "The C++ Programming Language", I came across this sentence on p. 108:

"The style of syntax analysis used is usually called recursive descent; it is a popular and straightforward top-down technique. In a language such as C++, in which function calls are relatively cheap, it is also efficient."

Can someone explain why C++ function calls are cheap? I'd be interested in a general explanation, i.e. what makes a function call cheap in any language, as well, if that's possible.

like image 879
jds Avatar asked May 03 '14 11:05

jds


People also ask

Are function calls expensive?

Speaking from personal experience, I write code in a proprietary language that is fairly modern in terms of capability, but function calls are ridiculously expensive, to the point where even typical for loops have to be optimized for speed: for(Integer index = 0, size = someList.

Do function calls slow down code C?

Yes method calls slow down the code execution a tiny little bit, if they a not inlined by the c#-compiler or the jit-compiler. However, unless your code runs in a loop and is executed a million times or so, you should really focus on producing clean, understandable and maintainable code.

How much overhead is a function call?

There is not much overhead at all, especially with small (inline-able) functions or even classes.

Do function calls have an overhead?

1) Function call overhead doesn't occur. 2) It also saves the overhead of push/pop variables on the stack when function is called. 3) It also saves overhead of a return call from a function. 4) When you inline a function, you may enable compiler to perform context specific optimization on the body of function.


2 Answers

Calling C or C++ functions (in particular when they are not virtual) is quite cheap since it involves only a few machine instructions, and a jump (with link to return address) to a known location.

On some other languages (e.g. Common Lisp, when applying an unknown variadic function), it may be more complex.

Actually, you should benchmark: many recent processors are out-of-order & superscalar, so are doing "several things at a time".

However, optimizing compilers are capable of marvellous tricks.

For many functional languages, a called function is in general a closure, and need some indirection (and also passing the closed values).

Some object oriented languages (like Smalltalk) may involve searching a dictionary of methods when invoking a selector (on an arbitrary receiver).

Interpreted languages may have a quite larger function call overhead.

like image 123
Basile Starynkevitch Avatar answered Nov 11 '22 06:11

Basile Starynkevitch


Function calls are cheap in C++ compared to most other languages for one reason: C++ is built upon the concept of function inlining, whereas (for example) java is built upon the concept of everything-is-a-virtual-function.

In C++, most of the time you're calling a function, you're not actually generating an call instruction. Especially when calling small or template functions, the compiler will most likely inline the code. In such case the function call overhead is simply zero.

Even when the function is not inlined, the compiler can make assumptions about what the function does For example: the windows X64 calling convention specifies that the registers R12-R15, XMM6-XMM15 should be saved by the caller. When calling a function, the compiler must generate code at the call site to save and restore these registers. But if the compiler can prove that the registers R12-R15, XMM6-XMM15 are not used by the called function such code can be omitted. This optimization is much harder when calling a virtual function.

Sometimes inlining is not possible. Common reasons include the function body not being available at compile time, of the function being too large. In that case the compiler generates an direct call instruction. However because the call target is fixed, the CPU can prefetch the instructions quite well. Although direct function calls are fast, there is still some overhead because the caller needs to save some registers on the stack, increase the stack pointer, etc.

Finally, when using an java function call or C++ function with the virtual keyword, the CPU will execute an virtual call instruction. The difference with an direct call is that the target is not fixed, but instead stored in in memory. The target function may change during the runtime of the program, which means that the CPU cannot always prefetch the data at the function location. Modern CPU's and JIT compilers have various tricks up their sleeve to predict the location of the target function, but it is still not as fast as direct calls.

tldr: function calls in C++ are fast because C++ implements inlining and by default uses direct calls over virtual calls. Many other languages do not implement inlining as well as C++ does and utilize virtual functions by default.

like image 40
Stefan Avatar answered Nov 11 '22 07:11

Stefan