From: Marco Costalba Date: Sun, 12 Feb 2012 15:02:13 +0000 (+0100) Subject: Templetize sliding attacks X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=7b4b65d7a95b3c8b40a11fe5b3efe959d5129008 Templetize sliding attacks No functional change and no speed regression, it seems to be even a bit faster on MSVC and gcc. Signed-off-by: Marco Costalba --- diff --git a/src/bitboard.cpp b/src/bitboard.cpp index c67c01a6..bdde9161 100644 --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@ -64,7 +64,7 @@ namespace { typedef unsigned (Fn)(Square, Bitboard); void init_magics(Bitboard table[], Bitboard* attacks[], Bitboard magics[], - Bitboard masks[], unsigned shifts[], Square deltas[], Fn get_index); + Bitboard masks[], unsigned shifts[], Square deltas[], Fn index); } @@ -219,13 +219,13 @@ void bitboards_init() { Square RDeltas[] = { DELTA_N, DELTA_E, DELTA_S, DELTA_W }; Square BDeltas[] = { DELTA_NE, DELTA_SE, DELTA_SW, DELTA_NW }; - init_magics(RTable, RAttacks, RMagics, RMasks, RShifts, RDeltas, r_index); - init_magics(BTable, BAttacks, BMagics, BMasks, BShifts, BDeltas, b_index); + init_magics(RTable, RAttacks, RMagics, RMasks, RShifts, RDeltas, magic_index); + init_magics(BTable, BAttacks, BMagics, BMasks, BShifts, BDeltas, magic_index); for (Square s = SQ_A1; s <= SQ_H8; s++) { - PseudoAttacks[BISHOP][s] = bishop_attacks_bb(s, 0); - PseudoAttacks[ROOK][s] = rook_attacks_bb(s, 0); + PseudoAttacks[BISHOP][s] = attacks_bb(s, 0); + PseudoAttacks[ROOK][s] = attacks_bb(s, 0); PseudoAttacks[QUEEN][s] = PseudoAttacks[BISHOP][s] | PseudoAttacks[ROOK][s]; } @@ -290,7 +290,7 @@ namespace { // use the so called "fancy" approach. void init_magics(Bitboard table[], Bitboard* attacks[], Bitboard magics[], - Bitboard masks[], unsigned shifts[], Square deltas[], Fn get_index) { + Bitboard masks[], unsigned shifts[], Square deltas[], Fn index) { int MagicBoosters[][8] = { { 3191, 2184, 1310, 3618, 2091, 1308, 2452, 3996 }, { 1059, 3608, 605, 3234, 3326, 38, 2029, 3043 } }; @@ -342,7 +342,7 @@ namespace { // effect of verifying the magic. for (i = 0; i < size; i++) { - Bitboard& attack = attacks[s][get_index(s, occupancy[i])]; + Bitboard& attack = attacks[s][index(s, occupancy[i])]; if (attack && attack != reference[i]) break; diff --git a/src/bitboard.h b/src/bitboard.h index 24ae794b..7a39a500 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -116,43 +116,28 @@ inline Bitboard in_front_bb(Color c, Square s) { } -/// Functions for computing sliding attack bitboards. rook_attacks_bb(), -/// bishop_attacks_bb() and queen_attacks_bb() all take a square and a -/// bitboard of occupied squares as input, and return a bitboard representing -/// all squares attacked by a rook, bishop or queen on the given square. +/// Functions for computing sliding attack bitboards. Function attacks_bb() takes +/// a square and a bitboard of occupied squares as input, and returns a bitboard +/// representing all squares attacked by Pt (bishop or rook) on the given square. +template +FORCE_INLINE unsigned magic_index(Square s, Bitboard occ) { -#if defined(IS_64BIT) + Bitboard* const Masks = Pt == ROOK ? RMasks : BMasks; + Bitboard* const Magics = Pt == ROOK ? RMagics : BMagics; + unsigned* const Shifts = Pt == ROOK ? RShifts : BShifts; -FORCE_INLINE unsigned r_index(Square s, Bitboard occ) { - return unsigned(((occ & RMasks[s]) * RMagics[s]) >> RShifts[s]); -} - -FORCE_INLINE unsigned b_index(Square s, Bitboard occ) { - return unsigned(((occ & BMasks[s]) * BMagics[s]) >> BShifts[s]); -} - -#else // if !defined(IS_64BIT) - -FORCE_INLINE unsigned r_index(Square s, Bitboard occ) { - unsigned lo = unsigned(occ) & unsigned(RMasks[s]); - unsigned hi = unsigned(occ >> 32) & unsigned(RMasks[s] >> 32); - return (lo * unsigned(RMagics[s]) ^ hi * unsigned(RMagics[s] >> 32)) >> RShifts[s]; -} - -FORCE_INLINE unsigned b_index(Square s, Bitboard occ) { - unsigned lo = unsigned(occ) & unsigned(BMasks[s]); - unsigned hi = unsigned(occ >> 32) & unsigned(BMasks[s] >> 32); - return (lo * unsigned(BMagics[s]) ^ hi * unsigned(BMagics[s] >> 32)) >> BShifts[s]; -} - -#endif + if (Is64Bit) + return unsigned(((occ & Masks[s]) * Magics[s]) >> Shifts[s]); -inline Bitboard rook_attacks_bb(Square s, Bitboard occ) { - return RAttacks[s][r_index(s, occ)]; + unsigned lo = unsigned(occ) & unsigned(Masks[s]); + unsigned hi = unsigned(occ >> 32) & unsigned(Masks[s] >> 32); + return (lo * unsigned(Magics[s]) ^ hi * unsigned(Magics[s] >> 32)) >> Shifts[s]; } -inline Bitboard bishop_attacks_bb(Square s, Bitboard occ) { - return BAttacks[s][b_index(s, occ)]; +template +inline Bitboard attacks_bb(Square s, Bitboard occ) { + Bitboard** const Attacks = Pt == ROOK ? RAttacks : BAttacks; + return Attacks[s][magic_index(s, occ)]; } diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 745d1a30..e2d8ac33 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -487,9 +487,9 @@ namespace { if (Piece == KNIGHT || Piece == QUEEN) b = pos.attacks_from(s); else if (Piece == BISHOP) - b = bishop_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(QUEEN, Us)); + b = attacks_bb(s, pos.occupied_squares() & ~pos.pieces(QUEEN, Us)); else if (Piece == ROOK) - b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(ROOK, QUEEN, Us)); + b = attacks_bb(s, pos.occupied_squares() & ~pos.pieces(ROOK, QUEEN, Us)); else assert(false); diff --git a/src/position.cpp b/src/position.cpp index f50677bb..9fa7c729 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -386,8 +386,8 @@ Bitboard Position::attackers_to(Square s, Bitboard occ) const { return (attacks_from(s, BLACK) & pieces(PAWN, WHITE)) | (attacks_from(s, WHITE) & pieces(PAWN, BLACK)) | (attacks_from(s) & pieces(KNIGHT)) - | (rook_attacks_bb(s, occ) & pieces(ROOK, QUEEN)) - | (bishop_attacks_bb(s, occ) & pieces(BISHOP, QUEEN)) + | (attacks_bb(s, occ) & pieces(ROOK, QUEEN)) + | (attacks_bb(s, occ) & pieces(BISHOP, QUEEN)) | (attacks_from(s) & pieces(KING)); } @@ -401,9 +401,9 @@ Bitboard Position::attacks_from(Piece p, Square s, Bitboard occ) { switch (type_of(p)) { - case BISHOP: return bishop_attacks_bb(s, occ); - case ROOK : return rook_attacks_bb(s, occ); - case QUEEN : return bishop_attacks_bb(s, occ) | rook_attacks_bb(s, occ); + case BISHOP: return attacks_bb(s, occ); + case ROOK : return attacks_bb(s, occ); + case QUEEN : return attacks_bb(s, occ) | attacks_bb(s, occ); default : return StepAttacksBB[p][s]; } } @@ -434,8 +434,8 @@ bool Position::move_attacks_square(Move m, Square s) const { return true; // Scan for possible X-ray attackers behind the moved piece - xray = (rook_attacks_bb(s, occ) & pieces(ROOK, QUEEN, color_of(piece))) - |(bishop_attacks_bb(s, occ) & pieces(BISHOP, QUEEN, color_of(piece))); + xray = (attacks_bb(s, occ) & pieces(ROOK, QUEEN, color_of(piece))) + |(attacks_bb(s, occ) & pieces(BISHOP, QUEEN, color_of(piece))); // Verify attackers are triggered by our move and not already existing return xray && (xray ^ (xray & attacks_from(s))); @@ -475,8 +475,8 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const { b ^= capsq; b |= to; - return !(rook_attacks_bb(ksq, b) & pieces(ROOK, QUEEN, them)) - && !(bishop_attacks_bb(ksq, b) & pieces(BISHOP, QUEEN, them)); + return !(attacks_bb(ksq, b) & pieces(ROOK, QUEEN, them)) + && !(attacks_bb(ksq, b) & pieces(BISHOP, QUEEN, them)); } // If the moving piece is a king, check whether the destination @@ -684,8 +684,8 @@ bool Position::move_gives_check(Move m, const CheckInfo& ci) const { b ^= from; b ^= capsq; b |= to; - return (rook_attacks_bb(ksq, b) & pieces(ROOK, QUEEN, us)) - ||(bishop_attacks_bb(ksq, b) & pieces(BISHOP, QUEEN, us)); + return (attacks_bb(ksq, b) & pieces(ROOK, QUEEN, us)) + ||(attacks_bb(ksq, b) & pieces(BISHOP, QUEEN, us)); } // Castling with check ? @@ -707,7 +707,7 @@ bool Position::move_gives_check(Move m, const CheckInfo& ci) const { b ^= rfrom; b |= rto; b |= kto; - return rook_attacks_bb(rto, b) & ksq; + return attacks_bb(rto, b) & ksq; } return false; @@ -1301,8 +1301,8 @@ int Position::see(Move m) const { // and scan for new X-ray attacks behind the attacker. b = stmAttackers & pieces(pt); occ ^= (b & (~b + 1)); - attackers |= (rook_attacks_bb(to, occ) & pieces(ROOK, QUEEN)) - | (bishop_attacks_bb(to, occ) & pieces(BISHOP, QUEEN)); + attackers |= (attacks_bb(to, occ) & pieces(ROOK, QUEEN)) + | (attacks_bb(to, occ) & pieces(BISHOP, QUEEN)); attackers &= occ; // Cut out pieces we've already done diff --git a/src/position.h b/src/position.h index 8229e71b..e471baea 100644 --- a/src/position.h +++ b/src/position.h @@ -345,10 +345,9 @@ inline Square Position::castle_rook_square(CastleRight f) const { template inline Bitboard Position::attacks_from(Square s) const { - return Pt == BISHOP ? bishop_attacks_bb(s, occupied_squares()) - : Pt == ROOK ? rook_attacks_bb(s, occupied_squares()) + return Pt == BISHOP || Pt == ROOK ? attacks_bb(s, occupied_squares()) : Pt == QUEEN ? attacks_from(s) | attacks_from(s) - : StepAttacksBB[Pt][s]; + : StepAttacksBB[Pt][s]; } template<>