mirror of
https://github.com/official-stockfish/Stockfish.git
synced 2026-07-22 12:47:08 +00:00
Optimize attacks
STC: https://tests.stockfishchess.org/tests/view/6a57f12c5529b8472df80e2a LLR: 2.95 (-2.94,2.94) <0.00,2.00> Total: 85856 W: 22400 L: 22037 D: 41419 Ptnml(0-2): 153, 8999, 24290, 9304, 182 closes https://github.com/official-stockfish/Stockfish/pull/6983 No functional change
This commit is contained in:
committed by
Joost VandeVondele
parent
b4ea9205a6
commit
d70dec7d6f
+1
-1
@@ -903,7 +903,7 @@ endif
|
||||
ifeq ($(pext),yes)
|
||||
CXXFLAGS += -DUSE_PEXT
|
||||
ifeq ($(comp),$(filter $(comp),gcc clang mingw icx))
|
||||
CXXFLAGS += -mbmi2 -DUSE_COMPTIME_ATTACKS
|
||||
CXXFLAGS += -mbmi2
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
+7
-22
@@ -24,15 +24,17 @@
|
||||
|
||||
namespace Stockfish::Attacks {
|
||||
|
||||
namespace {
|
||||
#ifdef USE_DUAL_HYPERBOLA_QUINT
|
||||
alignas(64) DualMagic DualMagics[SQUARE_NB];
|
||||
#endif
|
||||
|
||||
Bitboard LineBB[SQUARE_NB][SQUARE_NB];
|
||||
Bitboard BetweenBB[SQUARE_NB][SQUARE_NB];
|
||||
Bitboard RayPassBB[SQUARE_NB][SQUARE_NB];
|
||||
|
||||
#ifdef USE_DUAL_HYPERBOLA_QUINT
|
||||
alignas(64) DualMagic DualMagics[SQUARE_NB];
|
||||
#else
|
||||
namespace {
|
||||
|
||||
#ifndef USE_DUAL_HYPERBOLA_QUINT
|
||||
alignas(64) Magic Magics[SQUARE_NB][2];
|
||||
#endif
|
||||
|
||||
@@ -187,28 +189,11 @@ void init() {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_DUAL_HYPERBOLA_QUINT
|
||||
const DualMagic& dual_magic(Square s) { return DualMagics[s]; }
|
||||
#else
|
||||
#ifndef USE_DUAL_HYPERBOLA_QUINT
|
||||
const Magic& magic(Square s, PieceType pt) {
|
||||
assert((pt == BISHOP || pt == ROOK) && is_ok(s));
|
||||
return Magics[s][pt - BISHOP];
|
||||
}
|
||||
#endif
|
||||
|
||||
Bitboard line_bb(Square s1, Square s2) {
|
||||
assert(is_ok(s1) && is_ok(s2));
|
||||
return LineBB[s1][s2];
|
||||
}
|
||||
|
||||
Bitboard between_bb(Square s1, Square s2) {
|
||||
assert(is_ok(s1) && is_ok(s2));
|
||||
return BetweenBB[s1][s2];
|
||||
}
|
||||
|
||||
Bitboard ray_pass_bb(Square s1, Square s2) {
|
||||
assert(is_ok(s1) && is_ok(s2));
|
||||
return RayPassBB[s1][s2];
|
||||
}
|
||||
|
||||
} // namespace Stockfish::Attacks
|
||||
|
||||
+30
-4
@@ -22,6 +22,7 @@
|
||||
#include <cassert>
|
||||
#include <array>
|
||||
#include <initializer_list>
|
||||
#include <utility>
|
||||
|
||||
#include "types.h"
|
||||
#include "bitboard.h"
|
||||
@@ -135,7 +136,9 @@ struct alignas(32) DualMagic {
|
||||
}
|
||||
};
|
||||
|
||||
const DualMagic& dual_magic(Square s);
|
||||
extern DualMagic DualMagics[SQUARE_NB];
|
||||
|
||||
inline const DualMagic& dual_magic(Square s) { return DualMagics[s]; }
|
||||
|
||||
#else
|
||||
// Magic holds all magic bitboards relevant data for a single square
|
||||
@@ -164,9 +167,24 @@ const Magic& magic(Square s, PieceType pt);
|
||||
|
||||
#endif
|
||||
|
||||
Bitboard line_bb(Square s1, Square s2);
|
||||
Bitboard between_bb(Square s1, Square s2);
|
||||
Bitboard ray_pass_bb(Square s1, Square s2);
|
||||
extern Bitboard LineBB[SQUARE_NB][SQUARE_NB];
|
||||
extern Bitboard BetweenBB[SQUARE_NB][SQUARE_NB];
|
||||
extern Bitboard RayPassBB[SQUARE_NB][SQUARE_NB];
|
||||
|
||||
inline Bitboard line_bb(Square s1, Square s2) {
|
||||
assert(is_ok(s1) && is_ok(s2));
|
||||
return LineBB[s1][s2];
|
||||
}
|
||||
|
||||
inline Bitboard between_bb(Square s1, Square s2) {
|
||||
assert(is_ok(s1) && is_ok(s2));
|
||||
return BetweenBB[s1][s2];
|
||||
}
|
||||
|
||||
inline Bitboard ray_pass_bb(Square s1, Square s2) {
|
||||
assert(is_ok(s1) && is_ok(s2));
|
||||
return RayPassBB[s1][s2];
|
||||
}
|
||||
|
||||
// Returns the bitboard of target square for the given step
|
||||
// from the given square. If the step is off the board, returns empty bitboard.
|
||||
@@ -304,6 +322,14 @@ inline Bitboard attacks_bb(Square s, Bitboard occupied) {
|
||||
#endif
|
||||
}
|
||||
|
||||
inline std::pair<Bitboard, Bitboard> both_attacks_bb(Square s, Bitboard occupied) {
|
||||
#ifdef USE_DUAL_HYPERBOLA_QUINT
|
||||
return dual_magic(s).both_attacks_bb(occupied);
|
||||
#else
|
||||
return {attacks_bb<BISHOP>(s, occupied), attacks_bb<ROOK>(s, occupied)};
|
||||
#endif
|
||||
}
|
||||
|
||||
// Returns the attacks by the given piece
|
||||
// assuming the board is occupied according to the passed Bitboard.
|
||||
// Sliding piece attacks do not continue past an occupied square.
|
||||
|
||||
+15
-11
@@ -470,11 +470,12 @@ void Position::set_check_info() const {
|
||||
update_slider_blockers(BLACK);
|
||||
|
||||
Square ksq = square<KING>(~sideToMove);
|
||||
const auto [bishopAttacks, rookAttacks] = both_attacks_bb(ksq, pieces());
|
||||
|
||||
st->checkSquares[PAWN] = attacks_bb<PAWN>(ksq, ~sideToMove);
|
||||
st->checkSquares[KNIGHT] = attacks_bb<KNIGHT>(ksq);
|
||||
st->checkSquares[BISHOP] = attacks_bb<BISHOP>(ksq, pieces());
|
||||
st->checkSquares[ROOK] = attacks_bb<ROOK>(ksq, pieces());
|
||||
st->checkSquares[BISHOP] = bishopAttacks;
|
||||
st->checkSquares[ROOK] = rookAttacks;
|
||||
st->checkSquares[QUEEN] = st->checkSquares[BISHOP] | st->checkSquares[ROOK];
|
||||
st->checkSquares[KING] = 0;
|
||||
}
|
||||
@@ -641,8 +642,9 @@ void Position::update_slider_blockers(Color c) const {
|
||||
// Slider attacks use the occupied bitboard to indicate occupancy.
|
||||
Bitboard Position::attackers_to(Square s, Bitboard occupied) const {
|
||||
|
||||
return (attacks_bb<ROOK>(s, occupied) & pieces(ROOK, QUEEN))
|
||||
| (attacks_bb<BISHOP>(s, occupied) & pieces(BISHOP, QUEEN))
|
||||
const auto [bishopAttacks, rookAttacks] = both_attacks_bb(s, occupied);
|
||||
|
||||
return (rookAttacks & pieces(ROOK, QUEEN)) | (bishopAttacks & pieces(BISHOP, QUEEN))
|
||||
| (attacks_bb<PAWN>(s, BLACK) & pieces(WHITE, PAWN))
|
||||
| (attacks_bb<PAWN>(s, WHITE) & pieces(BLACK, PAWN))
|
||||
| (attacks_bb<KNIGHT>(s) & pieces(KNIGHT)) | (attacks_bb<KING>(s) & pieces(KING));
|
||||
@@ -791,10 +793,10 @@ bool Position::gives_check(Move m) const {
|
||||
case EN_PASSANT : {
|
||||
Square capsq = make_square(file_of(to), rank_of(from));
|
||||
Bitboard b = (pieces() ^ from ^ capsq) | to;
|
||||
const auto [bishopAttacks, rookAttacks] = both_attacks_bb(square<KING>(~sideToMove), b);
|
||||
|
||||
return (attacks_bb<ROOK>(square<KING>(~sideToMove), b) & pieces(sideToMove, QUEEN, ROOK))
|
||||
| (attacks_bb<BISHOP>(square<KING>(~sideToMove), b)
|
||||
& pieces(sideToMove, QUEEN, BISHOP));
|
||||
return (rookAttacks & pieces(sideToMove, QUEEN, ROOK))
|
||||
| (bishopAttacks & pieces(sideToMove, QUEEN, BISHOP));
|
||||
}
|
||||
default : //CASTLING
|
||||
{
|
||||
@@ -1189,8 +1191,9 @@ void Position::update_piece_threats(Piece pc,
|
||||
const Bitboard occupied = pieces();
|
||||
const Bitboard rookQueens = pieces(ROOK, QUEEN);
|
||||
const Bitboard bishopQueens = pieces(BISHOP, QUEEN);
|
||||
const Bitboard rAttacks = attacks_bb<ROOK>(s, occupied);
|
||||
const Bitboard bAttacks = attacks_bb<BISHOP>(s, occupied);
|
||||
const auto attacks = both_attacks_bb(s, occupied);
|
||||
const Bitboard bAttacks = attacks.first;
|
||||
const Bitboard rAttacks = attacks.second;
|
||||
const Bitboard occupiedNoK = occupied ^ pieces(KING);
|
||||
|
||||
Bitboard sliders = (rookQueens & rAttacks) | (bishopQueens & bAttacks);
|
||||
@@ -1508,8 +1511,9 @@ bool Position::see_ge(Move m, int threshold) const {
|
||||
assert(swap >= res);
|
||||
occupied ^= least_significant_square_bb(bb);
|
||||
|
||||
attackers |= (attacks_bb<BISHOP>(to, occupied) & pieces(BISHOP, QUEEN))
|
||||
| (attacks_bb<ROOK>(to, occupied) & pieces(ROOK, QUEEN));
|
||||
const auto [bishopAttacks, rookAttacks] = both_attacks_bb(to, occupied);
|
||||
attackers |=
|
||||
(bishopAttacks & pieces(BISHOP, QUEEN)) | (rookAttacks & pieces(ROOK, QUEEN));
|
||||
}
|
||||
|
||||
else // KING
|
||||
|
||||
Reference in New Issue
Block a user