Author: Gerd Isenberg
Date: 12:02:41 03/04/05
Go up one level in this thread
On March 04, 2005 at 09:51:14, Antonio Senatore wrote:
>Hi friends:
>
>I'm rewriting my engine so it can use bitboards now. However, something curious
>is happening. After having implemented with quite success the use of bitboards
>in others functions, now I'm trying to apply them in my evaluation function. As
>much as possible, I attempted to make the changes statement by statement to
>observe in what way the changes affected the speed of the engine. And here is
>where I am confused.
>
>So far, to determine if a passed pawn was or not sustained by its king, I used
>the following code (for a white pawn):
>
> if ((abs(column[wking_pos]-column[wpawn_pos]) <= 1) &&
>(abs(row[wking_pos]-row[wpawn_pos]) <= 1)) {
> ....
> etc.
> }
>
> where:
> 0 <= wking_pos <= 63 // 0 = A1, 1 = B1, etc.
> 0 <= wpawn_pos <= 63
>
Hi Antonio,
i guess most often the branches are predicted correctly in your bench, as you
may have not really random positions with pawns and king. As Bo already
mentioned, if the first compare is false the whole and-term needs no further
computation which might be often the case.
>
>I changed that code for the following:
>
> if (king_attack[wpawn_pos] & WhiteKing) {
> ....
> etc.
> }
>
>For my surprise, the code that uses bitboards is slower than the first one
>(according to some own bench tests), not much, but slower after all. How can it
>be possible? Because in the first case I make two comparisons and use the abs()
>function twice meanwhile in the second case I only make a bitwise-AND operation
>(of course, with 64 bit numbers in a 32 bit system, but even so, I think it
>should be faster) Can anyone tell me what I'm doing bad? Additionally, the same
>thing happens to me with:
>
>If (!(king_attack[wking_pos] & WhitePieces)) {
> ....
> etc.
>}
>
>that I attempted to use to see if the white king is or not surrounded for, at
>least, one own piece. Surprisingly, the code that makes the same thing by
>checking square by square (on the eight squares that surround the king) is a bit
>faster. I work with MSVC++ 6.0
It depends on your test pattern and how randomly they change (how many passers?)
- often a good predictable leading condition (more code) pays off.
Successive replacement of fast, well predictable 32-bit code with your bitboard
stuff with additional memory accesses may chaotically result in slower
execution speed with todays sensitive processors with huge heuristics and
caches. You may also have different results on P4, Athlon32 or later with AMD64
in 64-bit mode.
IMHO bitboards become more efficient by avoiding loops and random conditional
jumps - but that requires some redesign. The idea is to stay in 2**sq setwise
bitboard metric as long as possible, rather than using the square metric too
early - looking for properties setwise, rather than in inner loops.
E.g. your king defended passers:
WhitePassers = WhitePawns & ~filldown( blackPawns | blackPawnAttacks );
if ( WhitePassers ) { ....
WhitePassersDefByKing = king_attack[wking_pos] & WhitePassers;
while ( WhitePassersDefByKing ) traverse....;
}
...
// Kogge-Stone parallel prefix algorithm
// by Steffan Westcott
BitBoard fillDown(BitBoard b)
{
b |= b >> 8;
b |= b >> 16;
return b |= b >> 32;
}
>
>Many thanks in advance for any comentary that you can do.
Welcome thinking bitboards!
>
>Regards
>Antonio
Cheers,
Gerd
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.