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 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})
{
const Color c = Color(perspective ^ color);
@@ -236,14 +240,14 @@ void FullThreats::append_active_indices(Color perspective, const Position& pos,
if (c == WHITE)
{
process_pawn_attacks(shift<NORTH_EAST>(cPawns) & occupied, NORTH_EAST);
process_pawn_attacks(shift<NORTH_WEST>(cPawns) & occupied, NORTH_WEST);
process_pawn_attacks(shift<NORTH_EAST>(cPawns) & pawnTargets, NORTH_EAST);
process_pawn_attacks(shift<NORTH_WEST>(cPawns) & pawnTargets, NORTH_WEST);
process_pawn_attacks(shift<NORTH>(pushers), NORTH);
}
else
{
process_pawn_attacks(shift<SOUTH_WEST>(cPawns) & occupied, SOUTH_WEST);
process_pawn_attacks(shift<SOUTH_EAST>(cPawns) & occupied, SOUTH_EAST);
process_pawn_attacks(shift<SOUTH_WEST>(cPawns) & pawnTargets, SOUTH_WEST);
process_pawn_attacks(shift<SOUTH_EAST>(cPawns) & pawnTargets, SOUTH_EAST);
process_pawn_attacks(shift<SOUTH>(pushers), SOUTH);
}
}
@@ -255,7 +259,8 @@ void FullThreats::append_active_indices(Color perspective, const Position& pos,
while (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)
{
Square to = pop_lsb(attacks);
+33 -10
View File
@@ -1167,6 +1167,10 @@ void write_multiple_dirties(const Position& p,
}
#endif
constexpr bool can_slider_threat(Piece pc, Piece slider) {
return type_of(pc) != QUEEN || type_of(slider) == QUEEN;
}
template<bool ComputeRay>
void Position::update_piece_threats(Piece pc,
bool putPiece,
@@ -1179,10 +1183,11 @@ void Position::update_piece_threats(Piece pc,
const Bitboard bishopQueens = pieces(BISHOP, QUEEN);
const Bitboard rAttacks = attacks_bb<ROOK>(s, occupied);
const Bitboard bAttacks = attacks_bb<BISHOP>(s, occupied);
const Bitboard kings = pieces(KING);
Bitboard occupiedNoK = occupied ^ kings;
const Bitboard occupiedNoK = occupied ^ pieces(KING);
Bitboard sliders = (rookQueens & rAttacks) | (bishopQueens & bAttacks);
Bitboard directSliders = type_of(pc) == QUEEN ? sliders & pieces(QUEEN) : sliders;
auto process_sliders = [&](bool addDirectAttacks) {
while (sliders)
{
@@ -1197,10 +1202,11 @@ void Position::update_piece_threats(Piece pc,
{
const Square threatenedSq = lsb(discovered);
const Piece threatenedPc = piece_on(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);
}
};
@@ -1219,11 +1225,11 @@ void Position::update_piece_threats(Piece pc,
Bitboard threatened = attacks_bb(pc, s, occupied) & occupiedNoK;
Bitboard incoming_threats =
(PseudoAttacks[KNIGHT][s] & knights) | (PseudoAttacks[KING][s] & kings);
Bitboard incoming_threats = PseudoAttacks[KNIGHT][s] & knights;
// Compute both incoming and outgoing pawn threats. Incoming pawn pushers are only
// added if 'pc' is a pawn.
Bitboard pawnThreats = 0;
if (type_of(pc) == PAWN)
{
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);
incoming_threats |= whiteAttacks & blackPawns;
incoming_threats |= blackAttacks & whitePawns;
pawnThreats = whiteAttacks & blackPawns;
pawnThreats |= blackAttacks & whitePawns;
}
else
{
incoming_threats |=
pawnThreats =
(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
DirtyThreat dt_template{pc, NO_PIECE, s, Square(0), putPiece};
write_multiple_dirties<DirtyThreat::ThreatenedSqOffset, DirtyThreat::ThreatenedPcOffset>(
*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};
write_multiple_dirties<DirtyThreat::PcSqOffset, DirtyThreat::PcOffset>(*this, all_attackers,
@@ -1273,7 +1296,7 @@ void Position::update_piece_threats(Piece pc,
}
else
{
incoming_threats |= sliders;
incoming_threats |= directSliders;
}
#ifndef USE_AVX512ICL