Re: vtable performance of important function in multiple inheritance
andrew_nuss@yahoo.com wrote:
Hi,
I have an abstract interface:
struct StreamIntf {
~StreamIntf() {}
virtual int NextChar () = 0; // this must be FAST
};
Then I have another somewhat abstract interface:
class EObject {
};
and,
class EStreamIntf : public StreamIntf, public EObject {
// provide a real implementation that normally pulls the next
character from a buffer
// and only does an io read when the buffer is exhausted.
virtual int NextChar ();
};
and finally,
class EStream_io : public EStreamIntf {
// implement functions that actually read buffers
};
The question is: in the declaration of EStreamIntf, does the order of
subclasses listed matter in terms of the vtable performance of the
NextChar() function? Will this impact the performance of the virtual
members of the EObject functions provided by EStream_io and
EStreamIntf?
My guess is that if the performance of NextChar() outweighs all other
considerations, then StreamIntf should be listed first in the list of
subclasses of EStreamIntf. My second guess is that it does not matter,
that the performance will be the same as in virtual function calls of
single inheritance.
First of all, you should note that all this is applicable only if you
are performing calls through pointers or references to base classes.
Assuming of course, that that is true, most(probably not all) compilers
use something called a vtable(VTBL) for performing such tricks. This is
the same as calling a function using a function pointer. It is
essentially an indirect function call. So, there is one more level of
indirection involved. The VTBL comtains the function addresses, and the
function itself is represented as an offset into the VTBL. So,
something like this actually happens when you do an indirect function
call.
base_prt->foo()
Translates to:
base_ptr->_tbl[index_of_foo]();
Which is what happens in many places like the linux kernel(VFS layer).
So, you don't need to worry about it too much.
However, if you think that there is a direct relationship between the
time taken for a function call, and the amount of indirection involved,
then you are mistaken.
Let's delve a bit deep into a particular architecture, say x86. Here,
there is something called as a branch logic built into the processor.
There are generally 2 types of predictions that happen:
[1] Static branch prediction.
[2] Dynamic branch prediction.
Since this is a C++ group, I shall not go too deep and let you find out
more.
However, cutting a long story short, it would be sufficient to say that
indirect branches(through function pointers) are not subject to branch
prediction, so you have pipeline stalls. Hence the performance hit when
we use virtual functions.
So, you should first profile the code, and find out that the culprit is
actually who[or what] you think it is....
Regards,
-Dhruv.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]