Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > does virtualizing all methods slow C++ down ?

Reply
Thread Tools

does virtualizing all methods slow C++ down ?

 
 
Lynn McGuire
Guest
Posts: n/a
 
      09-06-2011
Does virtualizing all methods slow C++ down ? We
virtualize all methods as a matter of course since
we use groups of objects all over the place. To
illustrate this I have included the top portion of
our header files:

class GenGroup : public DataGroup
{
public:
int transferingDataNow;
public:
// constructor
GenGroup ();
GenGroup (const GenGroup & rhs);
GenGroup & operator = (const GenGroup & rhs);
// destructor
virtual ~GenGroup ();
virtual GenGroup * clone () { return new GenGroup ( * this); }
virtual void makeUnitsInput (InputCollection * anInpCol);
virtual void reinitStreamBox (FmFile * FMFile);
virtual DataDescriptor * descriptor (int aSymbol, int version);
....

Thanks
Lynn
 
Reply With Quote
 
 
 
 
Christopher
Guest
Posts: n/a
 
      09-06-2011
On Sep 6, 11:31*am, Lynn McGuire <l...@winsim.com> wrote:
> Does virtualizing all methods slow C++ down ? *We
> virtualize all methods as a matter of course since
> we use groups of objects all over the place. *To
> illustrate this I have included the top portion of
> our header files:
>
> class GenGroup : public DataGroup
> {
> public:
> * * int transferingDataNow;
> public:
> * * * *// *constructor
> * * GenGroup ();
> * * GenGroup (const GenGroup & rhs);
> * * GenGroup & operator = (const GenGroup & rhs);
> * * * *// *destructor
> * * virtual ~GenGroup ();
> * * virtual GenGroup * clone () { return new GenGroup ( * this); }
> * * virtual void makeUnitsInput (InputCollection * anInpCol);
> * * virtual void reinitStreamBox (FmFile * FMFile);
> * * virtual DataDescriptor * descriptor (int aSymbol, int version);
> ...
>
> Thanks
> Lynn


If you virtualize one, there is no cost for virtualizing the others.
There is a cost associated with virtualizing one method. See the FAQ.

I wouldn't virtualize every single method in every single class
though. That is just not thoughtful design. When I see a virtual
method, I assume the author INTENDED for the class to be derived from.
Surely, you have a concrete class somewhere.

 
Reply With Quote
 
 
 
 
Alain Ketterlin
Guest
Posts: n/a
 
      09-06-2011
Lynn McGuire <> writes:

> Does virtualizing all methods slow C++ down ? We
> virtualize all methods as a matter of course since
> we use groups of objects all over the place.


Not sure I understand what you mean, but yes, virtualizing all
(non-really-virtual) methods will slow things down, in cases where the
compiler cannot statically decide the class where the method is defined.
In the worst case:

- all calls through a reference or pointer will be indirect calls
- all other calls will be direct calls.

The branch predictor may help here, but you still pay some price. In
your example:

> virtual GenGroup * clone () { return new GenGroup ( * this); }


the compiler would normally (probably) inline any call to this method in
the non-virtual case. With virtual, all calls to this method through a
ref/pointer will be translated into an indirect call.

(I know, cloning usually requires dynamic binding, I used this example
because it was the only method potentially inlinable.)

C++11 provides the "final" qualifier, which may help here. Whether it is
taken into account depends on your compiler.

-- Alain.
 
Reply With Quote
 
Lynn McGuire
Guest
Posts: n/a
 
      09-06-2011
On 9/6/2011 12:00 PM, Christopher wrote:
> On Sep 6, 11:31 am, Lynn McGuire<l...@winsim.com> wrote:
>> Does virtualizing all methods slow C++ down ? We
>> virtualize all methods as a matter of course since
>> we use groups of objects all over the place. To
>> illustrate this I have included the top portion of
>> our header files:
>>
>> class GenGroup : public DataGroup
>> {
>> public:
>> int transferingDataNow;
>> public:
>> // constructor
>> GenGroup ();
>> GenGroup (const GenGroup& rhs);
>> GenGroup& operator = (const GenGroup& rhs);
>> // destructor
>> virtual ~GenGroup ();
>> virtual GenGroup * clone () { return new GenGroup ( * this); }
>> virtual void makeUnitsInput (InputCollection * anInpCol);
>> virtual void reinitStreamBox (FmFile * FMFile);
>> virtual DataDescriptor * descriptor (int aSymbol, int version);
>> ...
>>
>> Thanks
>> Lynn

>
> If you virtualize one, there is no cost for virtualizing the others.
> There is a cost associated with virtualizing one method. See the FAQ.
>
> I wouldn't virtualize every single method in every single class
> though. That is just not thoughtful design. When I see a virtual
> method, I assume the author INTENDED for the class to be derived from.
> Surely, you have a concrete class somewhere.


We have so many methods in our 600 classes and 700K lines
of code that we are not sure what needs to be virtual and
does not. So we do all to keep from missing 1, 2 or 20.

Thanks,
Lynn
 
Reply With Quote
 
Lynn McGuire
Guest
Posts: n/a
 
      09-06-2011
On 9/6/2011 12:12 PM, Alain Ketterlin wrote:
> Lynn McGuire<> writes:
>
>> Does virtualizing all methods slow C++ down ? We
>> virtualize all methods as a matter of course since
>> we use groups of objects all over the place.

>
> Not sure I understand what you mean, but yes, virtualizing all
> (non-really-virtual) methods will slow things down, in cases where the
> compiler cannot statically decide the class where the method is defined.
> In the worst case:
>
> - all calls through a reference or pointer will be indirect calls
> - all other calls will be direct calls.
>
> The branch predictor may help here, but you still pay some price. In
> your example:
>
>> virtual GenGroup * clone () { return new GenGroup ( * this); }

>
> the compiler would normally (probably) inline any call to this method in
> the non-virtual case. With virtual, all calls to this method through a
> ref/pointer will be translated into an indirect call.
>
> (I know, cloning usually requires dynamic binding, I used this example
> because it was the only method potentially inlinable.)
>
> C++11 provides the "final" qualifier, which may help here. Whether it is
> taken into account depends on your compiler.
>
> -- Alain.


Thanks, I had not thought about the direct calls just
directly binding to the proper method. I'll bet that
there are few direct calls in our code though as we
have many children classes.

ObjPtr -> DataGroup -> GenGroup

ObjPtr -> DataGroup -> NodeGroup -> StreamGroup

are a couple of example lineages.

Lynn
 
Reply With Quote
 
Christopher
Guest
Posts: n/a
 
      09-06-2011
On Sep 6, 2:09*pm, Lynn McGuire <l...@winsim.com> wrote:
> On 9/6/2011 12:00 PM, Christopher wrote:
>
>
>
>
>
> > On Sep 6, 11:31 am, Lynn McGuire<l...@winsim.com> *wrote:
> >> Does virtualizing all methods slow C++ down ? *We
> >> virtualize all methods as a matter of course since
> >> we use groups of objects all over the place. *To
> >> illustrate this I have included the top portion of
> >> our header files:

>
> >> class GenGroup : public DataGroup
> >> {
> >> public:
> >> * * *int transferingDataNow;
> >> public:
> >> * * * * // *constructor
> >> * * *GenGroup ();
> >> * * *GenGroup (const GenGroup& *rhs);
> >> * * *GenGroup& *operator = (const GenGroup& *rhs);
> >> * * * * // *destructor
> >> * * *virtual ~GenGroup ();
> >> * * *virtual GenGroup * clone () { return new GenGroup ( * this); }
> >> * * *virtual void makeUnitsInput (InputCollection * anInpCol);
> >> * * *virtual void reinitStreamBox (FmFile * FMFile);
> >> * * *virtual DataDescriptor * descriptor (int aSymbol, int version);
> >> ...

>
> >> Thanks
> >> Lynn

>
> > If you virtualize one, there is no cost for virtualizing the others.
> > There is a cost associated with virtualizing one method. See the FAQ.

>
> > I wouldn't virtualize every single method in every single class
> > though. That is just not thoughtful design. When I see a virtual
> > method, I assume the author INTENDED for the class to be derived from.
> > Surely, you have a concrete class somewhere.

>
> We have so many methods in our 600 classes and 700K lines
> of code that we are not sure what needs to be virtual and
> does not. *So we do all to keep from missing 1, 2 or 20.
>
> Thanks,
> Lynn- Hide quoted text -
>
> - Show quoted text -



Bad design doesn't make up for a bad process.

Surely, you have unit tests for these classes? Surely those tests
would show whether the expected behavior of a method call resolving to
the derived vs the base is occurring?


 
Reply With Quote
 
jacob navia
Guest
Posts: n/a
 
      09-06-2011
Le 06/09/11 21:13, Lynn McGuire a écrit :
> Thanks, I had not thought about the direct calls just
> directly binding to the proper method. I'll bet that
> there are few direct calls in our code though as we
> have many children classes.
>
> ObjPtr -> DataGroup -> GenGroup
>
> ObjPtr -> DataGroup -> NodeGroup -> StreamGroup
>
> are a couple of example lineages.
>
> Lynn


This is completely ridiculous. An indirect call vs a direct call
will cost you some pipeline turbulence and the cache may be flushed,
really not a big deal.

Have you MEASURED the slowdown? Is it significant in relationship
to OTHER improvements in your code?

Have you profiled your code to KNOW where it is spending 90% of the
time?

Before you answer THOSE questions, worrying about direc/indirect
calls is WASTED time and effort.
 
Reply With Quote
 
Alain Ketterlin
Guest
Posts: n/a
 
      09-06-2011
jacob navia <> writes:

> Le 06/09/11 21:13, Lynn McGuire a écrit :
>> Thanks, I had not thought about the direct calls just
>> directly binding to the proper method. I'll bet that
>> there are few direct calls in our code though as we
>> have many children classes.
>>
>> ObjPtr -> DataGroup -> GenGroup
>>
>> ObjPtr -> DataGroup -> NodeGroup -> StreamGroup
>>
>> are a couple of example lineages.
>>
>> Lynn

>
> This is completely ridiculous. An indirect call vs a direct call
> will cost you some pipeline turbulence and the cache may be flushed,
> really not a big deal.


Depends on the code. With lots of small methods (a la Java, with
getters/setters all over the place), it may be significant, mainly
because of the impossibility to inline. Take any program, compile it
with inlining disabled: the difference may be significant.

> Have you MEASURED the slowdown? Is it significant in relationship
> to OTHER improvements in your code?


Hard to measure. You need to change tens/hundreds of classes...

> Have you profiled your code to KNOW where it is spending 90% of the
> time?


In the case I mention above (many small functions), the overhead would
be spread over a large part of the code. Profiling becomes less useful.

> Before you answer THOSE questions, worrying about direc/indirect
> calls is WASTED time and effort.


I've just done this on a piece code that was evaluating an expression
tree on each vertex of a 4D grid, with an insane number of
floating-point ops. Incredible speedup (~120). Granted, the original was
over-engineered, and this may be a corner case.

Regarding Lynn's case, I would say you're right: he may be better off
keeping his current design safe rather than trying to save a few cycles.

-- Alain.
 
Reply With Quote
 
Lynn McGuire
Guest
Posts: n/a
 
      09-06-2011
On 9/6/2011 2:57 PM, jacob navia wrote:
> Le 06/09/11 21:13, Lynn McGuire a écrit :
>> Thanks, I had not thought about the direct calls just
>> directly binding to the proper method. I'll bet that
>> there are few direct calls in our code though as we
>> have many children classes.
>>
>> ObjPtr -> DataGroup -> GenGroup
>>
>> ObjPtr -> DataGroup -> NodeGroup -> StreamGroup
>>
>> are a couple of example lineages.
>>
>> Lynn

>
> This is completely ridiculous. An indirect call vs a direct call
> will cost you some pipeline turbulence and the cache may be flushed, really not a big deal.
>
> Have you MEASURED the slowdown? Is it significant in relationship
> to OTHER improvements in your code?
>
> Have you profiled your code to KNOW where it is spending 90% of the
> time?
>
> Before you answer THOSE questions, worrying about direc/indirect
> calls is WASTED time and effort.


I am not planning on changing our design, it works very well
and gets an amazing amount of work done in the amount of
code written. After reading the "Generally, are the programs
written by C++ slower than written by C 10% ?" thread, I was
just wondering about the major difference between C and C++
in our code. In the long and short runs, I would say that
the overhead is more than worth the automatic object method
lookups. More than !

Thanks,
Lynn
 
Reply With Quote
 
Lynn McGuire
Guest
Posts: n/a
 
      09-06-2011
On 9/6/2011 3:40 PM, Alain Ketterlin wrote:
> jacob navia<> writes:
>
>> Le 06/09/11 21:13, Lynn McGuire a écrit :
>>> Thanks, I had not thought about the direct calls just
>>> directly binding to the proper method. I'll bet that
>>> there are few direct calls in our code though as we
>>> have many children classes.
>>>
>>> ObjPtr -> DataGroup -> GenGroup
>>>
>>> ObjPtr -> DataGroup -> NodeGroup -> StreamGroup
>>>
>>> are a couple of example lineages.
>>>
>>> Lynn

>>
>> This is completely ridiculous. An indirect call vs a direct call
>> will cost you some pipeline turbulence and the cache may be flushed,
>> really not a big deal.

>
> Depends on the code. With lots of small methods (a la Java, with
> getters/setters all over the place), it may be significant, mainly
> because of the impossibility to inline. Take any program, compile it
> with inlining disabled: the difference may be significant.
>
>> Have you MEASURED the slowdown? Is it significant in relationship
>> to OTHER improvements in your code?

>
> Hard to measure. You need to change tens/hundreds of classes...
>
>> Have you profiled your code to KNOW where it is spending 90% of the
>> time?

>
> In the case I mention above (many small functions), the overhead would
> be spread over a large part of the code. Profiling becomes less useful.
>
>> Before you answer THOSE questions, worrying about direc/indirect
>> calls is WASTED time and effort.

>
> I've just done this on a piece code that was evaluating an expression
> tree on each vertex of a 4D grid, with an insane number of
> floating-point ops. Incredible speedup (~120). Granted, the original was
> over-engineered, and this may be a corner case.
>
> Regarding Lynn's case, I would say you're right: he may be better off
> keeping his current design safe rather than trying to save a few cycles.
>
> -- Alain.


You are more than correct, I was just wondering. In fact, we
saved millions of cycles by porting our code from Smalltalk
to C++. We had to do it anyway, our Smalltalk variant was
Win16 (don't even go there !) without a Win32 port. I would
not be surprised if we got a 100X speedup by converting to
C++ and Win32. Our current design is solid and will not be
changed - we have many other dragons to slay.

Thanks,
Lynn
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: slow slow slow! Expert lino fitter Computer Support 5 12-12-2008 04:00 PM
Re: slow slow slow! chuckcar Computer Support 0 12-10-2008 11:25 PM
Re: slow slow slow! Beauregard T. Shagnasty Computer Support 2 12-10-2008 09:03 PM
Re: slow slow slow! Expert lino fitter Computer Support 0 12-10-2008 02:33 PM
Is there a way to find the class methods of a class, just like'methods' finds the instance methods? Kenneth McDonald Ruby 5 09-26-2008 03:09 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57