Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #9810 > unrolled thread
| Started by | Lynn McGuire <lmc@winsim.com> |
|---|---|
| First post | 2011-09-06 11:31 -0500 |
| Last post | 2011-09-08 05:34 -0700 |
| Articles | 14 on this page of 34 — 17 participants |
Back to article view | Back to comp.lang.c++
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]
| From | Joshua Maurice <joshuamaurice@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2011-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]
| From | Nobody <nobody@nowhere.com> |
|---|---|
| Date | 2011-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]
| From | zindorsky <nephi.allred@gmail.com> |
|---|---|
| Date | 2011-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]
| From | "Kevin P. Fleming" <news@kpfleming.us> |
|---|---|
| Date | 2011-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]
| From | Nobody <nobody@nowhere.com> |
|---|---|
| Date | 2011-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]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2011-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]
| From | Goran <goran.pusic@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2011-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]
| From | Jorgen Grahn <grahn+nntp@snipabacken.se> |
|---|---|
| Date | 2011-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]
| From | Goran <goran.pusic@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2011-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]
| From | Goran <goran.pusic@gmail.com> |
|---|---|
| Date | 2011-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]
| From | ld <laurent.deniau@gmail.com> |
|---|---|
| Date | 2011-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