Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #9810 > unrolled thread

does virtualizing all methods slow C++ down ?

Started byLynn McGuire <lmc@winsim.com>
First post2011-09-06 11:31 -0500
Last post2011-09-08 05:34 -0700
Articles 14 on this page of 34 — 17 participants

Back to article view | Back to comp.lang.c++


Contents

  does virtualizing all methods slow C++ down ? Lynn McGuire <lmc@winsim.com> - 2011-09-06 11:31 -0500
    Re: does virtualizing all methods slow C++ down ? Christopher <cpisz@austin.rr.com> - 2011-09-06 10:00 -0700
      Re: does virtualizing all methods slow C++ down ? Lynn McGuire <lmc@winsim.com> - 2011-09-06 14:09 -0500
        Re: does virtualizing all methods slow C++ down ? Christopher <cpisz@austin.rr.com> - 2011-09-06 12:35 -0700
          Re: does virtualizing all methods slow C++ down ? "Kevin P. Fleming" <news@kpfleming.us> - 2011-09-06 16:41 -0500
        Re: does virtualizing all methods slow C++ down ? "Balog Pal" <pasa@lib.hu> - 2011-09-11 12:02 +0200
      Re: does virtualizing all methods slow C++ down ? "Thomas J. Gritzan" <phygon_antispam@gmx.de> - 2011-09-07 02:42 +0200
        Re: does virtualizing all methods slow C++ down ? Noah Roberts <roberts.noah@gmail.com> - 2011-09-07 07:39 -0700
          Re: does virtualizing all methods slow C++ down ? Richard Damon <news.x.richarddamon@xoxy.net> - 2011-09-07 11:46 -0400
      Re: does virtualizing all methods slow C++ down ? Nobody <nobody@nowhere.com> - 2011-09-07 01:45 +0100
    Re: does virtualizing all methods slow C++ down ? Alain Ketterlin <alain@dpt-info.u-strasbg.fr> - 2011-09-06 19:12 +0200
      Re: does virtualizing all methods slow C++ down ? Lynn McGuire <lmc@winsim.com> - 2011-09-06 14:13 -0500
        Re: does virtualizing all methods slow C++ down ? jacob navia <jacob@spamsink.net> - 2011-09-06 21:57 +0200
          Re: does virtualizing all methods slow C++ down ? Alain Ketterlin <alain@dpt-info.u-strasbg.fr> - 2011-09-06 22:40 +0200
            Re: does virtualizing all methods slow C++ down ? Lynn McGuire <lmc@winsim.com> - 2011-09-06 16:13 -0500
              Re: does virtualizing all methods slow C++ down ? Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-09-07 08:01 +0000
                Re: does virtualizing all methods slow C++ down ? Lynn McGuire <lmc@winsim.com> - 2011-09-14 12:08 -0500
                  Re: does virtualizing all methods slow C++ down ? Lynn McGuire <lmc@winsim.com> - 2011-09-14 14:04 -0500
          Re: does virtualizing all methods slow C++ down ? Lynn McGuire <lmc@winsim.com> - 2011-09-06 16:11 -0500
            Re: does virtualizing all methods slow C++ down ? Paavo Helde <myfirstname@osa.pri.ee> - 2011-09-07 11:44 -0500
              Re: does virtualizing all methods slow C++ down ? Joshua Maurice <joshuamaurice@gmail.com> - 2011-09-07 14:11 -0700
                Re: does virtualizing all methods slow C++ down ? Paavo Helde <myfirstname@osa.pri.ee> - 2011-09-08 01:26 -0500
                Re: does virtualizing all methods slow C++ down ? Nobody <nobody@nowhere.com> - 2011-09-08 07:37 +0100
                Re: does virtualizing all methods slow C++ down ? zindorsky <nephi.allred@gmail.com> - 2011-09-09 10:20 -0700
                  Re: does virtualizing all methods slow C++ down ? "Kevin P. Fleming" <news@kpfleming.us> - 2011-09-10 11:48 -0400
                    Re: does virtualizing all methods slow C++ down ? Nobody <nobody@nowhere.com> - 2011-09-10 17:58 +0100
    Re: does virtualizing all methods slow C++ down ? Juha Nieminen <nospam@thanks.invalid> - 2011-09-07 06:19 +0000
    Re: does virtualizing all methods slow C++ down ? Goran <goran.pusic@gmail.com> - 2011-09-06 23:52 -0700
      Re: does virtualizing all methods slow C++ down ? Juha Nieminen <nospam@thanks.invalid> - 2011-09-07 07:57 +0000
        Re: does virtualizing all methods slow C++ down ? Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-09-07 10:39 +0000
        Re: does virtualizing all methods slow C++ down ? Goran <goran.pusic@gmail.com> - 2011-09-07 04:30 -0700
          Re: does virtualizing all methods slow C++ down ? Juha Nieminen <nospam@thanks.invalid> - 2011-09-07 13:04 +0000
            Re: does virtualizing all methods slow C++ down ? Goran <goran.pusic@gmail.com> - 2011-09-07 06:18 -0700
    Re: does virtualizing all methods slow C++ down ? ld <laurent.deniau@gmail.com> - 2011-09-08 05:34 -0700

Page 2 of 2 — ← Prev page 1 [2]


#9909

FromJoshua Maurice <joshuamaurice@gmail.com>
Date2011-09-07 14:11 -0700
Message-ID<4b21a180-0317-45b2-850e-709f7a03c605@k9g2000vbd.googlegroups.com>
In reply to#9908
On Sep 7, 9:44 am, Paavo Helde <myfirstn...@osa.pri.ee> wrote:
> (for example,
> some compilers provide extensions to convert a virtual function pointer
> into a non-virtual one which can then be used inside the loop, providing
> better optimization possibilities).

I don't know what that means. You can already get a member function
pointer. Perhaps this extension allows you to say "take this member
function pointer and this pointer-to-object, and resolve the member
function pointer down into a new function pointer like thingy which
you can use on that pointer-to-object, but not other objects of
different dynamic type"? Still, that's changing effectively "one
indirection and one function pointer call" to just "one function
pointer call". It's still a function call through a function pointer.
I don't see how a compiler C++ extension could change a virtual
function call into a vanilla function call - that is, I don't see how
it could be done to allow for compile time inline code expansion, and
that's what really matters.

Now, compilers can do inline code expansion of virtual function calls
in some cases if they're really good, but you don't need C++
extensions for that, just a better optimizer. I don't see what a C++
extension would do.

[toc] | [prev] | [next] | [standalone]


#9914

FromPaavo Helde <myfirstname@osa.pri.ee>
Date2011-09-08 01:26 -0500
Message-ID<Xns9F5A6008E2745myfirstnameosapriee@216.196.109.131>
In reply to#9909
Joshua Maurice <joshuamaurice@gmail.com> wrote in news:4b21a180-0317-
45b2-850e-709f7a03c605@k9g2000vbd.googlegroups.com:

> On Sep 7, 9:44 am, Paavo Helde <myfirstn...@osa.pri.ee> wrote:
>> (for example,
>> some compilers provide extensions to convert a virtual function 
pointer
>> into a non-virtual one which can then be used inside the loop, 
providing
>> better optimization possibilities).
> 
> I don't know what that means. You can already get a member function
> pointer. Perhaps this extension allows you to say "take this member
> function pointer and this pointer-to-object, and resolve the member
> function pointer down into a new function pointer like thingy which
> you can use on that pointer-to-object, but not other objects of
> different dynamic type"? Still, that's changing effectively "one
> indirection and one function pointer call" to just "one function
> pointer call". It's still a function call through a function pointer.
> I don't see how a compiler C++ extension could change a virtual
> function call into a vanilla function call - that is, I don't see how
> it could be done to allow for compile time inline code expansion, and
> that's what really matters.

Probably I messed something up. It appears the vague recollection I had 
was about a similar but distinct topic (Extracting the function pointer 
from a bound pointer to member function):

http://gcc.gnu.org/onlinedocs/gcc-3.0.4/gcc_6.html#SEC122

This is about pointers to member functions, and how to avoid virtual 
lookups in tight loops when calling a member function repeatedly through 
such a pointer. This is probably not relevant to OP's concerns. And yes, 
this won't still do any inlining.

Cheers
Paavo

[toc] | [prev] | [next] | [standalone]


#9916

FromNobody <nobody@nowhere.com>
Date2011-09-08 07:37 +0100
Message-ID<pan.2011.09.08.06.37.21.453000@nowhere.com>
In reply to#9909
On Wed, 07 Sep 2011 14:11:05 -0700, Joshua Maurice wrote:

>> some compilers provide extensions to convert a virtual function pointer
>> into a non-virtual one which can then be used inside the loop, providing
>> better optimization possibilities).
> 
> I don't know what that means.

I think that he is referring to automatic specialisation, i.e.:

	if (&obj->method == &Base::method)
		// generated code using inlined Base::method
	else if (&obj->method == &Derived::method)
		// generated code using inlined Derived::method
	...
	else
		// generated code calling obj->method() via vtable

This gets pretty hairy if there are multiple objects and many known
subclasses. And it only works if the method definitions are available.

[toc] | [prev] | [next] | [standalone]


#9991

Fromzindorsky <nephi.allred@gmail.com>
Date2011-09-09 10:20 -0700
Message-ID<644bc212-031d-408c-aad8-f666fdefd3d1@u10g2000prn.googlegroups.com>
In reply to#9909
On Sep 7, 3:11 pm, Joshua Maurice <joshuamaur...@gmail.com> wrote:
> It's still a function call through a function pointer.
> I don't see how a compiler C++ extension could change a virtual
> function call into a vanilla function call - that is, I don't see how
> it could be done to allow for compile time inline code expansion, and
> that's what really matters.

In theory at least, a compiler could create self-modifying code that
would convert virtual function calls to direct function calls. That
is, at runtime after the code gets the function pointer from the
vtable, it could also rewrite the machine code inside the tight loop
to directly call that function. Of course, as a practical matter it
would be pretty hard for a compiler to do that, but it is
theoretically possible.

[toc] | [prev] | [next] | [standalone]


#10033

From"Kevin P. Fleming" <news@kpfleming.us>
Date2011-09-10 11:48 -0400
Message-ID<4e6b86e7$0$26286$a8266bb1@newsreader.readnews.com>
In reply to#9991
On 09/09/2011 01:20 PM, zindorsky wrote:
> On Sep 7, 3:11 pm, Joshua Maurice<joshuamaur...@gmail.com>  wrote:
>> It's still a function call through a function pointer.
>> I don't see how a compiler C++ extension could change a virtual
>> function call into a vanilla function call - that is, I don't see how
>> it could be done to allow for compile time inline code expansion, and
>> that's what really matters.
>
> In theory at least, a compiler could create self-modifying code that
> would convert virtual function calls to direct function calls. That
> is, at runtime after the code gets the function pointer from the
> vtable, it could also rewrite the machine code inside the tight loop
> to directly call that function. Of course, as a practical matter it
> would be pretty hard for a compiler to do that, but it is
> theoretically possible.

Assuming a single-threaded environment :)

[toc] | [prev] | [next] | [standalone]


#10035

FromNobody <nobody@nowhere.com>
Date2011-09-10 17:58 +0100
Message-ID<pan.2011.09.10.16.58.16.316000@nowhere.com>
In reply to#10033
On Sat, 10 Sep 2011 11:48:56 -0400, Kevin P. Fleming wrote:

>> In theory at least, a compiler could create self-modifying code that
>> would convert virtual function calls to direct function calls. That
>> is, at runtime after the code gets the function pointer from the
>> vtable, it could also rewrite the machine code inside the tight loop
>> to directly call that function. Of course, as a practical matter it
>> would be pretty hard for a compiler to do that, but it is
>> theoretically possible.
> 
> Assuming a single-threaded environment :)

It would work in a multi-threaded environment provided that it can update
function pointers and/or jump instructions atomically.

A bigger problem nowadays would be W^X (write or execute but not both)
memory protection.

[toc] | [prev] | [next] | [standalone]


#9864

FromJuha Nieminen <nospam@thanks.invalid>
Date2011-09-07 06:19 +0000
Message-ID<4e670cf7$0$3067$7b1e8fa0@news.nbl.fi>
In reply to#9810
Lynn McGuire <lmc@winsim.com> wrote:
> Does virtualizing all methods slow C++ down ?

  The cost of calling a virtual function (compared to calling a normal
member function) is often greatly exaggerated. I once tested the speed
difference myself and the difference was not measurable (in other words,
both tests returned time values that were so close together that even
the variance between runs of the same test were larger).

  Of course my sample size is that of 1 (iow. I have tested it only in
one system with one compiler, using one specific test), so the result is
far from definitive. However, it does tell me that the difference is
quite minuscule in practice, and often overwhelmed by everything else
that happens when calling a function (pushing parameters onto the stack
and so on, which, depending on the amount and type of parameters, will
probably take a lot more clock cycles than the indirect virtual function
call.)

  However, this is comparing virtual functions with regular *non-inlined*
functions. Function inlining can have a much greater difference, and if
you virtualize an inline function, it might slow it down significantly
in comparison. (Either the compiler will not inline it at all, or else
it will have to add some kind of runtime conditional in the compiled code
to check if the function has been overridden.) Thus if you have for example
some really small getter/setter functions that are better inline and really
don't need to be virtual, don't make them.

[toc] | [prev] | [next] | [standalone]


#9866

FromGoran <goran.pusic@gmail.com>
Date2011-09-06 23:52 -0700
Message-ID<014eefda-2064-4b01-bb5a-3dd8a8de1cb9@o9g2000vbo.googlegroups.com>
In reply to#9810
On Sep 6, 6:31 pm, 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.

Yes, it's obviously slower to go through a virtual method than not.
Compiler might turn some of those into non-virtual and even inline it.
As others have said, you probably can't notice the slowdown. Not
unless something really degenerate is happening in the code (like,
you're spending most of the complete program time virtually calling
functions that are very shot and aren't virtual "in practice").

However, going "all virtual" is IMO pretty dumb. While it might look
as "designing for the future", in practice, it's nothing of the sort.
I think that you should try looking at your virtual functions and
check how many of them are actually overridden in derived classes, and
how. I bet you that overridden version can either be trivially
refactored back into a base class, or it requires so much knowledge of
the base's internals that it's going impossible to change the base
without affecting all derived classes. That "coupling through
inheritance" is poor design.

Goran

[toc] | [prev] | [next] | [standalone]


#9875

FromJuha Nieminen <nospam@thanks.invalid>
Date2011-09-07 07:57 +0000
Message-ID<4e6723f8$0$3069$7b1e8fa0@news.nbl.fi>
In reply to#9866
Goran <goran.pusic@gmail.com> wrote:
> Yes, it's obviously slower to go through a virtual method than not.

  How "obviously"? Do you have any actual measurement results?

[toc] | [prev] | [next] | [standalone]


#9886

FromJorgen Grahn <grahn+nntp@snipabacken.se>
Date2011-09-07 10:39 +0000
Message-ID<slrnj6eie8.gtj.grahn+nntp@frailea.sa.invalid>
In reply to#9875
On Wed, 2011-09-07, Juha Nieminen wrote:
> Goran <goran.pusic@gmail.com> wrote:
>> Yes, it's obviously slower to go through a virtual method than not.
>
>   How "obviously"? Do you have any actual measurement results?

Surely it's obvious?  Even TC++PL says so in various places.

If it's /measurably slower/ in a real situation is another thing. I
guess it very rarely is -- except for the missed opportunities for
inlining which many have mentioned.

/Jorgen

-- 
  // Jorgen Grahn <grahn@  Oo  o.   .     .
\X/     snipabacken.se>   O  o   .

[toc] | [prev] | [next] | [standalone]


#9895

FromGoran <goran.pusic@gmail.com>
Date2011-09-07 04:30 -0700
Message-ID<bdeaf8df-d663-40c0-a098-a8a52ebc093d@u26g2000yqu.googlegroups.com>
In reply to#9875
On Sep 7, 9:57 am, Juha Nieminen <nos...@thanks.invalid> wrote:
> Goran <goran.pu...@gmail.com> wrote:
> > Yes, it's obviously slower to go through a virtual method than not.
>
>   How "obviously"? Do you have any actual measurement results?

Obviously, no ;-). Do you really think it's the same/faster?

I was merely alluding to the usual implementation with call
instruction being read off the virtual method table. Hopping twice
(more, really) can't be faster than once :-).

Goran.

[toc] | [prev] | [next] | [standalone]


#9898

FromJuha Nieminen <nospam@thanks.invalid>
Date2011-09-07 13:04 +0000
Message-ID<4e676bc7$0$4376$7b1e8fa0@news.nbl.fi>
In reply to#9895
Goran <goran.pusic@gmail.com> wrote:
> On Sep 7, 9:57 am, Juha Nieminen <nos...@thanks.invalid> wrote:
>> Goran <goran.pu...@gmail.com> wrote:
>> > Yes, it's obviously slower to go through a virtual method than not.
>>
>>   How "obviously"? Do you have any actual measurement results?
> 
> Obviously, no ;-). Do you really think it's the same/faster?

  "Obviously" just could as well mean "significantly" (iow. the slowdown
is "obvious", ie. very noticeable).

  From my own tests there's no practical difference between a virtual
function call and a regular function call. Even if there's a clock cycle
or two of difference, it's so small that this difference gets completely
buried under everything else that is happening.

[toc] | [prev] | [next] | [standalone]


#9899

FromGoran <goran.pusic@gmail.com>
Date2011-09-07 06:18 -0700
Message-ID<43759e57-a67f-415b-ab33-bf09578b59f2@r21g2000yqr.googlegroups.com>
In reply to#9898
On Sep 7, 3:04 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
> Goran <goran.pu...@gmail.com> wrote:
> > On Sep 7, 9:57 am, Juha Nieminen <nos...@thanks.invalid> wrote:
> >> Goran <goran.pu...@gmail.com> wrote:
> >> > Yes, it's obviously slower to go through a virtual method than not.
>
> >> How "obviously"? Do you have any actual measurement results?
>
> > Obviously, no ;-). Do you really think it's the same/faster?
>
>   "Obviously" just could as well mean "significantly" (iow. the slowdown
> is "obvious", ie. very noticeable).
>
>   From my own tests there's no practical difference between a virtual
> function call and a regular function call.

We agree, don't we? In my first post, right after the "offending"
"obviously", I said (this time, with relevant emphasis):

As others have said, you probably CAN'T NOTICE the slowdown. Not
unless something REALLY DEGENERATE is happening in the code (like,
you're spending most of the complete program time virtually calling
functions that are very shot and aren't virtual "in practice").

To be quite honest I posted here more to bash generalized use of
"virtual". I care about that more than CPU cycles ;-).

Goran.

[toc] | [prev] | [next] | [standalone]


#9921

Fromld <laurent.deniau@gmail.com>
Date2011-09-08 05:34 -0700
Message-ID<5cdb1b1e-3e5b-413f-9548-289d3ebc7e84@i21g2000yqd.googlegroups.com>
In reply to#9810
On Sep 6, 6:31 pm, 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

To make things short,

- A polymorphic class in C++ is a class with at least one virtual
member function or one virtual base class.

- The memory extra cost in your polymorphic instance will be about one
pointer per branch having one polymorphic base class in your
inheritance DAG.

- The speed extra cost of a virtual call will be in general less than
25% compared to a monomorphic call (as soon as you really use an
abstract class for the call), up to possibly zero cost. But there is
situation where you can slow it down significantly like if the
overridden member function is using non trivial contravariant or
covariant argument (only "this" can be contravariant in c++) and
covariant return type. Then the compiler will have to apply thunks to
adjust properly the object offset back and forth to match its input
and ouput types to the virtual member function expectation.

Since you were talking about smalltalk in this thread, it is also
possible to write a message dispatcher which is as fast as late
binding (virtual call). My experience is that direct call, virtual
call or message dispatch don't make the difference (except for
expressivity and design). The matter is that polymorphic types (if
used as such) loose their value semantic (compared to concrete types)
and thus need to be dynamically created (allocated, cloned, etc). This
is where polymorphic code slow down significantly the runtime if it is
badly design.

Regards,

Laurent.

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | comp.lang.c++


csiph-web