Filter invalid threat pairs early

Passed STC:
LLR: 2.94 (-2.94,2.94) <0.00,2.00>
Total: 246400 W: 63981 L: 63391 D: 119028
Ptnml(0-2): 612, 26055, 69299, 26599, 635
https://tests.stockfishchess.org/tests/view/6a3fafbf3036e45021aebaa0

Measured 1% speedup locally on x86-64-avx512icl build (bench 512 1 16, 50 runs):

PASSED: speedup = +0.0104, P(speedup > 0) = 1.0000

closes https://github.com/official-stockfish/Stockfish/pull/6936

No functional change
This commit is contained in:
Syine Mineta
2026-07-03 20:22:16 +02:00
committed by Joost VandeVondele
parent d91c7f6eac
commit 83514e4970
2 changed files with 47 additions and 19 deletions
+10 -5
View File
@@ -212,6 +212,10 @@ void FullThreats::append_active_indices(Color perspective, const Position& pos,
const Bitboard occupied = pos.pieces(); const Bitboard occupied = pos.pieces();
const Bitboard pawns = pos.pieces(PAWN); const Bitboard pawns = pos.pieces(PAWN);
const Bitboard pawnTargets = pos.pieces(PAWN, KNIGHT, ROOK);
const Bitboard minorSliderTargets = pos.pieces(PAWN, KNIGHT, BISHOP, ROOK);
const Bitboard queenTargets = pos.pieces(PAWN, KNIGHT, BISHOP, ROOK, QUEEN);
for (Color color : {WHITE, BLACK}) for (Color color : {WHITE, BLACK})
{ {
const Color c = Color(perspective ^ color); const Color c = Color(perspective ^ color);
@@ -236,14 +240,14 @@ void FullThreats::append_active_indices(Color perspective, const Position& pos,
if (c == WHITE) if (c == WHITE)
{ {
process_pawn_attacks(shift<NORTH_EAST>(cPawns) & occupied, NORTH_EAST); process_pawn_attacks(shift<NORTH_EAST>(cPawns) & pawnTargets, NORTH_EAST);
process_pawn_attacks(shift<NORTH_WEST>(cPawns) & occupied, NORTH_WEST); process_pawn_attacks(shift<NORTH_WEST>(cPawns) & pawnTargets, NORTH_WEST);
process_pawn_attacks(shift<NORTH>(pushers), NORTH); process_pawn_attacks(shift<NORTH>(pushers), NORTH);
} }
else else
{ {
process_pawn_attacks(shift<SOUTH_WEST>(cPawns) & occupied, SOUTH_WEST); process_pawn_attacks(shift<SOUTH_WEST>(cPawns) & pawnTargets, SOUTH_WEST);
process_pawn_attacks(shift<SOUTH_EAST>(cPawns) & occupied, SOUTH_EAST); process_pawn_attacks(shift<SOUTH_EAST>(cPawns) & pawnTargets, SOUTH_EAST);
process_pawn_attacks(shift<SOUTH>(pushers), SOUTH); process_pawn_attacks(shift<SOUTH>(pushers), SOUTH);
} }
} }
@@ -255,7 +259,8 @@ void FullThreats::append_active_indices(Color perspective, const Position& pos,
while (bb) while (bb)
{ {
Square from = pop_lsb(bb); Square from = pop_lsb(bb);
Bitboard attacks = Attacks::attacks_bb(pt, from, occupied) & occupied; Bitboard targets = pt == KNIGHT || pt == QUEEN ? queenTargets : minorSliderTargets;
Bitboard attacks = Attacks::attacks_bb(pt, from, occupied) & targets;
while (attacks) while (attacks)
{ {
Square to = pop_lsb(attacks); Square to = pop_lsb(attacks);
+37 -14
View File
@@ -1167,6 +1167,10 @@ void write_multiple_dirties(const Position& p,
} }
#endif #endif
constexpr bool can_slider_threat(Piece pc, Piece slider) {
return type_of(pc) != QUEEN || type_of(slider) == QUEEN;
}
template<bool ComputeRay> template<bool ComputeRay>
void Position::update_piece_threats(Piece pc, void Position::update_piece_threats(Piece pc,
bool putPiece, bool putPiece,
@@ -1179,11 +1183,12 @@ void Position::update_piece_threats(Piece pc,
const Bitboard bishopQueens = pieces(BISHOP, QUEEN); const Bitboard bishopQueens = pieces(BISHOP, QUEEN);
const Bitboard rAttacks = attacks_bb<ROOK>(s, occupied); const Bitboard rAttacks = attacks_bb<ROOK>(s, occupied);
const Bitboard bAttacks = attacks_bb<BISHOP>(s, occupied); const Bitboard bAttacks = attacks_bb<BISHOP>(s, occupied);
const Bitboard kings = pieces(KING); const Bitboard occupiedNoK = occupied ^ pieces(KING);
Bitboard occupiedNoK = occupied ^ kings;
Bitboard sliders = (rookQueens & rAttacks) | (bishopQueens & bAttacks); Bitboard sliders = (rookQueens & rAttacks) | (bishopQueens & bAttacks);
auto process_sliders = [&](bool addDirectAttacks) { Bitboard directSliders = type_of(pc) == QUEEN ? sliders & pieces(QUEEN) : sliders;
auto process_sliders = [&](bool addDirectAttacks) {
while (sliders) while (sliders)
{ {
Square sliderSq = pop_lsb(sliders); Square sliderSq = pop_lsb(sliders);
@@ -1197,10 +1202,11 @@ void Position::update_piece_threats(Piece pc,
{ {
const Square threatenedSq = lsb(discovered); const Square threatenedSq = lsb(discovered);
const Piece threatenedPc = piece_on(threatenedSq); const Piece threatenedPc = piece_on(threatenedSq);
add_dirty_threat(dts, !putPiece, slider, threatenedPc, sliderSq, threatenedSq); if (can_slider_threat(threatenedPc, slider))
add_dirty_threat(dts, !putPiece, slider, threatenedPc, sliderSq, threatenedSq);
} }
if (addDirectAttacks) if (addDirectAttacks && can_slider_threat(pc, slider))
add_dirty_threat(dts, putPiece, slider, pc, sliderSq, s); add_dirty_threat(dts, putPiece, slider, pc, sliderSq, s);
} }
}; };
@@ -1218,12 +1224,12 @@ void Position::update_piece_threats(Piece pc,
const Bitboard blackPawns = pieces(BLACK, PAWN); const Bitboard blackPawns = pieces(BLACK, PAWN);
Bitboard threatened = attacks_bb(pc, s, occupied) & occupiedNoK; Bitboard threatened = attacks_bb(pc, s, occupied) & occupiedNoK;
Bitboard incoming_threats = Bitboard incoming_threats = PseudoAttacks[KNIGHT][s] & knights;
(PseudoAttacks[KNIGHT][s] & knights) | (PseudoAttacks[KING][s] & kings);
// Compute both incoming and outgoing pawn threats. Incoming pawn pushers are only // Compute both incoming and outgoing pawn threats. Incoming pawn pushers are only
// added if 'pc' is a pawn. // added if 'pc' is a pawn.
Bitboard pawnThreats = 0;
if (type_of(pc) == PAWN) if (type_of(pc) == PAWN)
{ {
Bitboard whiteAttacks = PawnPushOrAttacks[WHITE][s]; Bitboard whiteAttacks = PawnPushOrAttacks[WHITE][s];
@@ -1231,21 +1237,38 @@ void Position::update_piece_threats(Piece pc,
threatened |= (color_of(pc) == WHITE ? whiteAttacks : blackAttacks) & pieces(PAWN); threatened |= (color_of(pc) == WHITE ? whiteAttacks : blackAttacks) & pieces(PAWN);
incoming_threats |= whiteAttacks & blackPawns; pawnThreats = whiteAttacks & blackPawns;
incoming_threats |= blackAttacks & whitePawns; pawnThreats |= blackAttacks & whitePawns;
} }
else else
{ {
incoming_threats |= pawnThreats =
(attacks_bb<PAWN>(s, WHITE) & blackPawns) | (attacks_bb<PAWN>(s, BLACK) & whitePawns); (attacks_bb<PAWN>(s, WHITE) & blackPawns) | (attacks_bb<PAWN>(s, BLACK) & whitePawns);
} }
if (type_of(pc) == PAWN || type_of(pc) == KNIGHT || type_of(pc) == ROOK)
incoming_threats |= pawnThreats;
switch (type_of(pc))
{
case PAWN :
threatened &= pieces(PAWN, KNIGHT, ROOK);
break;
case BISHOP :
case ROOK :
threatened &= pieces(PAWN, KNIGHT, BISHOP, ROOK);
break;
default :
threatened &= occupiedNoK;
break;
}
#ifdef USE_AVX512ICL #ifdef USE_AVX512ICL
DirtyThreat dt_template{pc, NO_PIECE, s, Square(0), putPiece}; DirtyThreat dt_template{pc, NO_PIECE, s, Square(0), putPiece};
write_multiple_dirties<DirtyThreat::ThreatenedSqOffset, DirtyThreat::ThreatenedPcOffset>( write_multiple_dirties<DirtyThreat::ThreatenedSqOffset, DirtyThreat::ThreatenedPcOffset>(
*this, threatened, dt_template, dts); *this, threatened, dt_template, dts);
Bitboard all_attackers = sliders | incoming_threats; Bitboard all_attackers = directSliders | incoming_threats;
dt_template = {NO_PIECE, pc, Square(0), s, putPiece}; dt_template = {NO_PIECE, pc, Square(0), s, putPiece};
write_multiple_dirties<DirtyThreat::PcSqOffset, DirtyThreat::PcOffset>(*this, all_attackers, write_multiple_dirties<DirtyThreat::PcSqOffset, DirtyThreat::PcOffset>(*this, all_attackers,
@@ -1273,7 +1296,7 @@ void Position::update_piece_threats(Piece pc,
} }
else else
{ {
incoming_threats |= sliders; incoming_threats |= directSliders;
} }
#ifndef USE_AVX512ICL #ifndef USE_AVX512ICL