The cost of dynamic vs. static dispatch in C++
eli.thegreenplace.net
The cost of dynamic vs. static dispatch in C++
1–10 of 72 posts
Re: The cost of dynamic vs. static dispatch in C++
#2Virtual dispatch is useful for type erasure, when using abstract types from plugins, DLLs or generally "somebody elses code". IMHO, the valid use cases within a standalone program are actually fairly small.
Re: The cost of dynamic vs. static dispatch in C++
#3A key thing here is that inlining is what enables zero-cost abstractions in C++. A virtual call is slower than a regular call, but the main problem is that it builds a barrier that effectively stops inlining.
It'll be interesting to see how devirtualization in GCC will do for real world programs.
Re: The cost of dynamic vs. static dispatch in C++
#4Re: The cost of dynamic vs. static dispatch in C++
#5 for (unsigned i = 0; i tick(j);
}
}
I wouldn't go quite so far as to say that benchmarks with tight inner loops like this are completely useless, but they are nearly so.The author is clearly aware that the real world of performance is much bigger & more complex than his simple Petri dish. Credit to him for mentioning that. It's also really refreshing to see him analysing the optimised assembly.
The trouble with this approach is that it's tempting to draw simple conclusions. In this case, you might be tempted to conclude "CRTP always faster than virtual dispatch", when the truth is likely to be much more situation dependent.
I have seen a biggish project go though a lot of effort to switch to CRTP, only to see a negligible performance impact.
Re: The cost of dynamic vs. static dispatch in C++
#6 while(...) {
(obj->vtable[0])(...)
}
we could have void(*fn)(...) = obj->vtable[0]
while(...) {
fn(...)
}
which would avoid two redirections per inner loop! Actually, I'm almost sure that is what LuaJIT would do, and many other high-level programming languages could perform this optimization as well. However, maybe C is too low-level to be able to do that, and I don't know about C++.Re: The cost of dynamic vs. static dispatch in C++
#7Dynamic linking has more indirection than you might expect because the function addresses can't always just be put at the call site during the library load (the places where you would want to write the address can be in code that is read-only mmapped to aid in sharing memory between processes and to avoid loading unused stuff from disk).
Re: The cost of dynamic vs. static dispatch in C++
#8http://imagine-rt.blogspot.co.uk/2013/08/c-virtual-function-...
And this was with billions of calls to the functions...
Re: The cost of dynamic vs. static dispatch in C++
#9Instead of devirtualization, a simpler optimization, which would additionally also help in the dynamic case, is simple loop hoisting of the method pointer fetch. Instead of doing while(...) { (obj->vtable[0])(...) } we could have void(*fn)(...) = obj->vtable[0] while(...) { fn(...) } which would avoid two redirections per inner loop! Actually, I'm almost sure that is what LuaJIT would do, and many other high-level pr…
Re: The cost of dynamic vs. static dispatch in C++
#10for (unsigned i = 0; i tick(j); } } I wouldn't go quite so far as to say that benchmarks with tight inner loops like this are completely useless, but they are nearly so. The author is clearly aware that the real world of performance is much bigger & more complex than his simple Petri dish. Credit to him for mentioning that. It's also really refreshing to see him analysing the optimised assembly. The trouble with this…