Feature Request: nontrivial functions and vtable optimizations

Craig Black craigblack2 at cox.net
Thu Aug 14 19:55:05 PDT 2008


"Don" <nospam at nospam.com.au> wrote in message 
news:g7u5mr$261s$1 at digitalmars.com...
> Craig Black wrote:
>> "downs" <default_357-line at yahoo.de> wrote in message 
>> news:g7ribh$1vii$1 at digitalmars.com...
>>> The overhead of vtable calls is well known.
>>>
>>> For this reason, it may be worthwhile to include an optimization that 
>>> essentially checks if a certain class is only inherited from a few 
>>> times, like, <= three, in the visible program, and if so, replace vtable 
>>> calls with a tree of classinfo pointer comparisons and direct function 
>>> calls.
>>>
>>> When I did this manually in some hobbyist path tracing code, I gained 
>>> significant speed-ups, even though I didn't collect any hard numbers.
>>>
>>> So, for instance, the equivalent D code would look like so:
>>>
>>> class A { ... } class B : A { ... } class C : A { ... }
>>>
>>> A a = genSomeObj();
>>> // a.test();
>>> if (a.classinfo == typeid(B)) (cast(B)cast(void*) a).test(); // call as 
>>> if final
>>> else if (a.classinfo == typeid(C)) (cast(C)cast(void*) a).test(); // 
>>> dito
>>> else a.test(); // fallback
>>>
>>> Ideas?
>>
>> You are right.  Function pointer invokation tends to slow down processing 
>> because it doesn't cooperate well with pipelining and branch prediction.
>
> I don't think this is true any more.
> It was true in processors older than the Pentium M and AMD K10. On recent 
> CPUs, indirect jumps and calls are predicted as well as conditional 
> branches are. If you're seeing this kind of the speed difference, it's 
> something else (probably, more code is being executed).

To be fair, modern processors are quite sophisticated and do better than 
older ones with function pointers and vtables.  I don't mean to 
overemphasize the penalty of function pointer invokations.  They are usually 
relatively fast on modern processors.

Even so, they can still be the source of bottlenecks.  You should never 
think of a function pointer invokation as free.  Never assume that your 
compiler and processor are doing magical optimizations.  Modern processors 
can still have problems with branch prediction.  I speak from experience, 
and there are many others in the field that agree.

Obviously, you should always profile first since your function pointer 
invokations may not be a bottleneck at all.  It is going to depend on how 
often and how the function pointers are getting called.  From experience, I 
have had numerous performance problems with function pointer invokations. 
For example, I found a very severe bottleneck in my rendering loop that was 
caused due to a function pointer invokation.  It was destroying my 
performance.  In general, when I refactor my code to make less function 
pointer calls, I usually get significant measurable speedups.

-Craig 




More information about the Digitalmars-d mailing list