Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: Generating attack tables: Is this code good?

Author: Tim Foden

Date: 07:40:42 12/03/03

Go up one level in this thread


On December 03, 2003 at 10:04:01, Tord Romstad wrote:

>On December 03, 2003 at 06:25:35, Tim Foden wrote:
>
>>On December 01, 2003 at 06:57:13, Tord Romstad wrote:
>>
>>>void compute_attacks() {
>>>  int i, colour, *p, sq, tosq, piece;
>>>  uint16 mask, *attacks;
>>>
>>>  for(p=(int *)(Attacks+64), i=0; i<8; i++, p+=8)
>>>    *p = *(p+1) = *(p+2) = *(p+3) = 0;
>>>  for(p=(int *)(XAttacks+64), i=0; i<8; i++, p+=8)
>>>    *p = *(p+1) = *(p+2) = *(p+3) = 0;
>>>
>>>  attacks = Attacks;
>>>  for(i=0, colour=Colour; i<2; i++, colour^=1) {
>>>    for(sq=Pieces[colour].next; sq!=255; sq=Pieces[sq].next) {
>>>      for(p = &(PieceDirs[Board[sq]][0]); *p; p++) {
>>>	piece = Board[sq]; mask = PieceMasks[piece];
>>>	tosq = sq + *p;
>>>	while(1) {
>>>	  attacks[tosq] |= mask; attacks[tosq]++;
>>>	  if(!(Abilities[piece] & SLIDING) || Board[tosq] == OUTSIDE
>>>	     || Board[tosq] == WK || Board[tosq] == BK) break;
>>>	  if(Board[tosq]) {
>>>	    if(PieceColour(Board[tosq]) == PieceColour(piece) &&
>>>	       (DirectionType[*p] & Abilities[Board[tosq]])) {
>>>	      /* X-ray attack.  The &0xFF at the next time masks off
>>>               * the direct attack bits. */
>>>	      mask = PieceMasks[max(piece, Board[tosq])] & 0xFF;
>>>	      piece = Board[tosq]; }
>>>	    else break; }
>>>	  tosq += *p; }}}
>>>    attacks = XAttacks; }}
>>>
>>>From the initial position, I compute the attack tables about a million
>>>times per second with this code.  From WAC1, the rate drops to about
>>>700,000 times per second.  The high nodes/second count of Rebel (which
>>>has similar tables) makes me believe that it is possible to do this
>>>many times faster.
>>>
>>>Tord
>>
>>Hi Tord,
>
>Hi Tim, and thanks for the comments!
>
>>I had a brief look at this code... here are my comments:  :)
>>
>>1. It may be slightly faster to put the "attacks[tosq] =" line after the "if"
>>that is below it.  Try it and see.
>
>Faster, perhaps, but it would give wrong results.  No bits for non-sliding
>pieces would ever be set.

Ooops!  I missed that.  Maybe just move the Board[tosq] == OUTSIDE test here
then.


>>2. I feel that it will be slightly more common, and will be quicker to test,
>>whether the tosq is out of bounds, than to check for sliders.  I would therefore
>>try putting the Board[tosq] == OUTSIDE before the test for a slider.
>
>You're probably right about this one -- I'll give it a try.
>
>>3. The explicit tests for the Board[tosq] == WK and Board[tosq] == BK seem
>>strange.  This will surely be handled by the slider case anyway, so should never
>>be true (unless for some reason you have kings as being sliding pieces).
>
>No, the tests for Board[tosq]==WK and Board[tosq]==BK are really necessary.
>It is not handled by the slider case, because Abilities[piece]&SLIDING
>tests whether the piece that attacks tosq is sliding, not whether the
>king is sliding.
>
>The point of the test is to avoid generating x-ray attacks through a king.
>If there is a white bishop on d3 and a white pawn on e4, The bishop should
>be counted as one of the white attackers of the square f5.  But if the
>pawn on e4 is replaced by a white king, the bishop on d3 is no longer
>attacking f5.  This is the point of the tests.

Sorry, missed this too.  I should have looked at the code a little longer!  :)


>>4. Is PieceColour(piece) the same as colour?  If so you can replace
>>PieceColour(piece) with colour.
>
>You're right, of course.  How stupid of me to overlook this obvious
>improvement.
>
>>5. DirectionType[*p] is a constant for each direction.  It may be faster to look
>>this up once rather than many times.
>
>Perhaps.  I thought the compiler should be smart enough to do this for me,
>but perhaps it is worth trying.

Well, it's fairly easy to test.  If it doesn't pan out, you can keep it as it
is.


>>6. Taking constants outside the loops is generally a good idea.  It may be
>>better to reformulate the code so that piece and mask don't change, and use
>>piece2 and mask2 inside the while loop.  I know it isn't quite clear how to do
>>this, but it may be possible.  I.E. don't start the while loop at all for the
>>non-sliding cases.
>
>Yes, perhaps I could make something like this work (although I'm afraid
>it would make the code more complicated).  I'll have a look at it.

Well, it will be a few more lines of code for sure, but the logic may actually
be simpler, and/or more predictable, which in turn may produce a speedup.

Then again, having looked at the code again, I realise a bit more about what it
does, and it could be tricky to make simplifications but still keep the
functionality.


Cheers, Tim.

>>Well, thats all for now.  I hope some of it actaully helps!  :)
>
>I'm sure it does -- thanks a lot for your help!
>
>Tord



This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

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