www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Inlining Virtual Functions

reply dsimcha <dsimcha yahoo.com> writes:
According to the spec:

"Virtual functions are functions that are called indirectly through a function
pointer table, called a vtbl[], rather than directly. All non-static
non-private non-template member functions are virtual. This may sound
inefficient, but since the D compiler knows all of the class hierarchy when
generating code, all functions that are not overridden can be optimized to be
non-virtual. In fact, since C++ programmers tend to "when in doubt, make it
virtual", the D way of "make it virtual unless we can prove it can be made
non-virtual" results, on average, in many more direct function calls. It also
results in fewer bugs caused by not declaring a function virtual that gets
overridden."

Under what circumstances is this actually true?  As far as I can tell, there
is no way DMD could know about the whole class hierarchy when generating code,
given that in practice modules are compiled separately.  Not arguing that
methods should be made non-virtual by default, since the current behavior is
consistent with the "make it safe by default, efficient but unsafe if the
programmer asks" mentality, and one can always convert a function to
non-virtual by making it final.  However, I'm just curious under what
circumstances converting virtual functions into direct calls is actually
possible.
Feb 27 2009
parent bearophile <bearophileHUGS lycos.com> writes:
dsimcha:

 Under what circumstances is this actually true?
At the moment I think that spec is pure theory for DMD, even if it's worded to almost sound as the compiler already works like that :-)
As far as I can tell, there is no way DMD could know about the whole class
hierarchy when generating code, given that in practice modules are compiled
separately.<
I think with LDC it will be possible to perform global optimizations among different modules, allowing such optimization too, in some situations (LDC developers may confirm of deny this). HotSpot is able to analyze the call loci and compile and/or inline code dynamically. Sometimes it's able to turn a virtual dispatch into a direct call, sometimes such virtual dispatch is replaced with a branch with two possible direct calls, and sometimes it puts a test that allows a direct call in most cases or a virtual dispatch as fallback for the less common case. There are even more complex cases, but you often don't gain much more. Removing virtual calls speeds up code a little by itself, but then later it allows the compiler to inline methods, and this may speed up code significantly in inner loops. A possibility for D is runtime-driven optimization: you compiler and run the code, the compiler collects statistics on the virtual call sites (among many other kinds of statistics) and then you can re-compile your code letting the compiler use such run-time information to inline things, etc. Of course your test run must be significant of the final normal usage of your code, otherwise you optimize against the wrong things (while HotSpot runs concurrently of your code, so it surely collects real-world data). The GCC (and Intel) compiler is already able to perform such collection of run-time statistics, with -fprofile-generate and -fprofile-use, but I don't know if it uses such information to inline ex-virtual calls too. This too is related: http://www.digitalmars.com/ctg/trace.html Bye, bearophile
Feb 27 2009