Computer Chess Club Archives




Subject: Re: C and C++ --- NPS

Author: Robert Hyatt

Date: 21:58:30 12/25/02

Go up one level in this thread

On December 24, 2002 at 22:13:35, Matt Taylor wrote:

>On December 24, 2002 at 20:33:34, Gerd Isenberg wrote:
>>On December 23, 2002 at 21:33:50, Matt Taylor wrote:
>>>On December 23, 2002 at 21:29:08, Arshad F. Syed wrote:
>>>>Is there anyone here who has actually converted their C code to C++ while
>>>>keeping the NPS the same or even managed to improve upon it? Sune did mention
>>>>that he did so only at the cost of 15% degradation in speed. Why do people even
>>>>bother wasting their time with C++ for a chess program when it inevitably leads
>>>>to taking a hit in NPS? Regardless, of all the advice to simply inline the
>>>>functions, I have yet to see a living example of chess program code which
>>>>performed faster in C++.
>>>The biggest hit you take in C++ is virtual functions, and inevitably people use
>>>them. The virtual functions are very damaging due to the fact that they're
>>>implemented with a function pointer, and at the machine level it translates into
>>>an indirect call. The indirect calls branch mispredict because the CPU can't
>>>figure out ahead-of-time where you're calling to, and branch mispredicts are
>>Hi Matt,
>>really? The vtable index of a virtual function is a compile time constant.
>>Is an indirect call via register a mispredicted branch per se, even if the
>>register was loaded with this->vptr->someVfunctionPointer an appropriate time
>>before the indirect call occurs? What branch could be executed, other than the
>>determined indirect call?
>I spent a while perusing the Athlon optimization manual, and I don't see
>anything about that. Even in the Xeon optimization manual, it says little about
>this. I do recall reading it somewhere, but I have no idea where now.
>The one thing that the Xeon manual mentions is that, in static prediction,
>indirect branches are predicted as not taken. From my understanding of how
>dynamic branch prediction works, you would take the penalty once for each time
>you made the call. E.g. the following will eat 2 penalties:

I am hoping you are mis-interpreting this.  I don't believe there is _any_
"prediction" on an unconditional branch.  I believe that is referring to a
conditional branch to an address that is in a register...  It makes no sense
to even update the BTB for unconditional branches since there is nothing to
predict.  It _is_ going to branch.

>; Note esi is preserved across the call. I'm going to assume that ecx is, too.
>mov    esi, [ecx->SomeFunction]
>call   esi
>call   esi
>The dynamic prediction mechanism stores the -address- that you branch to, so if
>this were the body of a loop, you would eat the penalty twice, and every other
>prediction (assuming it didn't get wiped from the BTB) would pick correctly
>assuming you were calling to the same place. If you were to, say, cycle through
>an unsorted list of pieces and call a function for move generation, you would be
>eating major penalties because it would mispredict almost every time.
>The major problem with indirect branches is easily seen in the code sample
>there. Static prediction -can't- guess where it's going to go because it needs
>to know about the contents of esi at the front of the pipeline. It won't know
>where to continue executing until the u-op that assigns to esi retires.

There I agree.  But once esi is set, there is no prediction of any kind to
handle...  since this is an unconditional branch (or call, same thing).

>The alternative of switch/case will at -least- prefetch the correct code if it's
>small, and it has a chance of getting the prediction right.
>>>Unfortunately, not using virtual functions (mostly) defeats the benefits you
>>>would get from OO here.
>>>If you convert to C++ without using virtual functions, you probably won't take
>>>much of a hit at all. Personally, I've never seen a -need- to convert to C++. I
>>>can implement my OO in C, and it simplifies linking because C doesn't have name
>>But polymorphism is nice to have, even without virtual functions.
>>I don't believe that name mangling affects the linker a lot ;-)
>It's not a problem until you want to mix in some assembly or link to someone's C
>code or use code written in some other language. Then the
>"?#@#$%@$@#2#@@#$FunctionXYZ" names become very obnoxious.

This page took 0.01 seconds to execute

Last modified: Thu, 07 Jul 11 08:48:38 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.