August 15, 2008 Re: I was wrong. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to superdan | "superdan" <super@dan.org> wrote in message news:g82fpu$t53$1@digitalmars.com... > Jb Wrote: > > relax. No!!!!! ;-) Actualy yeah sorry if i came over a bit cranky. | |||
August 15, 2008 Re: Feature Request: nontrivial functions and vtable optimizations | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Christopher Wright | "Christopher Wright" <dhasenan@gmail.com> wrote in message news:g7uhpk$308b$2@digitalmars.com... > Craig Black wrote: >> Rather than relying on PGO, I would prefer the ability to assign a priorities to virtual functions in the code. This would indicate to the compiler what virtual functions will be called the most. >> >> -Craig > > Or you could wait a bit[1] and have LLVM do that for you, assuming you're willing to run LLVM bytecode. And considering it's LLVM, you could probably hack it to periodically dump the optimized code. So you'd optimize your application by fooling around with it for a couple hours. > > [1] "A bit" may be as long as a decade. I dunno. The LLVM based D compiler seems promising. Hopefully it will mature soon. -Craig | |||
August 15, 2008 Re: Feature Request: nontrivial functions and vtable optimizations | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Don | "Don" <nospam@nospam.com.au> wrote in message news:g7u5mr$261s$1@digitalmars.com... > Craig Black wrote: >> "downs" <default_357-line@yahoo.de> wrote in message news:g7ribh$1vii$1@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 | |||
August 15, 2008 Re: Feature Request: nontrivial functions and vtable optimizations | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jb | "Jb" <jb@nowhere.com> wrote in message news:g7ubhk$2hq5$1@digitalmars.com... > > "Craig Black" <cblack@ara.com> wrote in message news:g7s7o1$dpt$1@digitalmars.com... > (on x86 anyway). > > Virtual methods are in such high use that Intel and Amd have put a lot of effort into optimizing them. > > Replacing the function pointer with a conditional branch wont make it faster. It may or may not improve performance. Depends on the particular case. >> See Microsoft Visual C++ profile guided optimizations (PGO) "Virtual Call Speculation". Using PGO, the most commonly called virtual functions are optimized so that they do not require a function pointer invokation. > > The speedup you get from this is the inlining of the function, *not* the getting rid of the function pointer lookup. It still requires a lookup in the class info and a conditional branch to check that the "inlined function" is the correct match for the speculated object. > > That will still cost a whole pipline of cycles if wrongly predicted. You may be right in some cases. Profile to be sure. But experience has taught me to be wary of function pointer invokations, even on modern CPU's. If you want to believe that there is never a penalty for function pointer invokation go right ahead. After all, it's only two instructions right? Must be real fast. ;) -Craig | |||
August 15, 2008 Re: Feature Request: nontrivial functions and vtable optimizations | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Craig Black | "Craig Black" <craigblack2@cox.net> wrote in message news:g82rj4$1hqn$1@digitalmars.com... >> >> The speedup you get from this is the inlining of the function, *not* the getting rid of the function pointer lookup. It still requires a lookup in the class info and a conditional branch to check that the "inlined function" is the correct match for the speculated object. >> >> That will still cost a whole pipline of cycles if wrongly predicted. > > You may be right in some cases. Profile to be sure. But experience has taught me to be wary of function pointer invokations, even on modern CPU's. If you want to believe that there is never a penalty for function pointer invokation go right ahead. After all, it's only two instructions right? Must be real fast. ;) I'm not saying there's no penalty, im saying it's a penalty you cant escape if you want virtual functions. Function pointer invocations == conditional branches as far as modern branch predictors are concerned. You dont gain anything by replacing the former with the later. | |||
August 15, 2008 Re: Feature Request: nontrivial functions and vtable optimizations | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jb | "Jb" <jb@nowhere.com> wrote in message news:g843q6$104a$1@digitalmars.com... > > "Craig Black" <craigblack2@cox.net> wrote in message news:g82rj4$1hqn$1@digitalmars.com... >>> >>> The speedup you get from this is the inlining of the function, *not* the getting rid of the function pointer lookup. It still requires a lookup in the class info and a conditional branch to check that the "inlined function" is the correct match for the speculated object. >>> >>> That will still cost a whole pipline of cycles if wrongly predicted. >> >> You may be right in some cases. Profile to be sure. But experience has taught me to be wary of function pointer invokations, even on modern CPU's. If you want to believe that there is never a penalty for function pointer invokation go right ahead. After all, it's only two instructions right? Must be real fast. ;) > > I'm not saying there's no penalty, im saying it's a penalty you cant escape if you want virtual functions. > > Function pointer invocations == conditional branches as far as modern branch predictors are concerned. You dont gain anything by replacing the former with the later. I thought you were wrong about this so I did a micro-benchmark and it indicates that you are correct. With only 1 branch the performance of an if statement was exactly the same as a function pointer invokation. Function pointer invokations ended up being roughly 50% faster than a sequence of if-elses. I guess I stand corrected. -Craig | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply