mirror of
https://github.com/official-stockfish/Stockfish.git
synced 2026-07-23 05:07:14 +00:00
Improve update_piece_threats
passed on avx512ICL: LLR: 2.95 (-2.94,2.94) <0.00,2.00> Total: 30240 W: 8026 L: 7726 D: 14488 Ptnml(0-2): 95, 3235, 8171, 3513, 106 https://tests.stockfishchess.org/tests/view/69281d9ab23dfeae38cfeeb8 passed on generic architectures: LLR: 2.94 (-2.94,2.94) <0.00,2.00> Total: 73184 W: 19183 L: 18821 D: 35180 Ptnml(0-2): 258, 7988, 19744, 8338, 264 https://tests.stockfishchess.org/tests/view/6928ba11b23dfeae38cff276 subsequent cleanups tested as: LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 72480 W: 18678 L: 18502 D: 35300 Ptnml(0-2): 242, 7925, 19718, 8125, 230 https://tests.stockfishchess.org/tests/view/692a26adb23dfeae38cff566 We add an argument noRaysContaining, which skips all discoveries which contain all bits in the argument; if the argument is from | to, then this will eliminate the discovery. Separately, on AVX512ICL we can speed up the computation of DirtyThreats by moving from a pop_lsb loop to a vector extraction with vpcompressb. See PR for details. closes https://github.com/official-stockfish/Stockfish/pull/6453 No functional change
This commit is contained in:
committed by
Joost VandeVondele
parent
9e2ee13e77
commit
abd835dcbc
+80
-14
@@ -1052,8 +1052,51 @@ inline void add_dirty_threat(
|
||||
dts->list.push_back({pc, threatened, s, threatenedSq, PutPiece});
|
||||
}
|
||||
|
||||
#ifdef USE_AVX512ICL
|
||||
// Given a DirtyThreat template and bit offsets to insert the piece type and square, write the threats
|
||||
// present at the given bitboard.
|
||||
template<int SqShift, int PcShift>
|
||||
void write_multiple_dirties(const Position& p,
|
||||
Bitboard mask,
|
||||
DirtyThreat dt_template,
|
||||
DirtyThreats* dts) {
|
||||
static_assert(sizeof(DirtyThreat) == 4);
|
||||
|
||||
const __m512i board = _mm512_loadu_si512(p.piece_array().data());
|
||||
const __m512i AllSquares = _mm512_set_epi8(
|
||||
63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41,
|
||||
40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18,
|
||||
17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
|
||||
|
||||
const int dt_count = popcount(mask);
|
||||
assert(dt_count <= 16);
|
||||
|
||||
const __m512i template_v = _mm512_set1_epi32(dt_template.raw());
|
||||
auto* write = dts->list.make_space(dt_count);
|
||||
|
||||
// Extract the list of squares and upconvert to 32 bits. There are never more than 16
|
||||
// incoming threats so this is sufficient.
|
||||
__m512i threat_squares = _mm512_maskz_compress_epi8(mask, AllSquares);
|
||||
threat_squares = _mm512_cvtepi8_epi32(_mm512_castsi512_si128(threat_squares));
|
||||
|
||||
__m512i threat_pieces =
|
||||
_mm512_maskz_permutexvar_epi8(0x1111111111111111ULL, threat_squares, board);
|
||||
|
||||
// Shift the piece and square into place
|
||||
threat_squares = _mm512_slli_epi32(threat_squares, SqShift);
|
||||
threat_pieces = _mm512_slli_epi32(threat_pieces, PcShift);
|
||||
|
||||
const __m512i dirties =
|
||||
_mm512_ternarylogic_epi32(template_v, threat_squares, threat_pieces, 254 /* A | B | C */);
|
||||
_mm512_storeu_si512(reinterpret_cast<__m512i*>(write), dirties);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<bool PutPiece, bool ComputeRay>
|
||||
void Position::update_piece_threats(Piece pc, Square s, DirtyThreats* const dts) {
|
||||
void Position::update_piece_threats(Piece pc,
|
||||
Square s,
|
||||
DirtyThreats* const dts,
|
||||
Bitboard noRaysContaining) {
|
||||
const Bitboard occupied = pieces();
|
||||
const Bitboard rookQueens = pieces(ROOK, QUEEN);
|
||||
const Bitboard bishopQueens = pieces(BISHOP, QUEEN);
|
||||
@@ -1093,7 +1136,36 @@ void Position::update_piece_threats(Piece pc, Square s, DirtyThreats* const dts)
|
||||
}
|
||||
|
||||
threatened &= occupied;
|
||||
Bitboard sliders = (rookQueens & rAttacks) | (bishopQueens & bAttacks);
|
||||
Bitboard incoming_threats =
|
||||
(PseudoAttacks[KNIGHT][s] & knights) | (attacks_bb<PAWN>(s, WHITE) & blackPawns)
|
||||
| (attacks_bb<PAWN>(s, BLACK) & whitePawns) | (PseudoAttacks[KING][s] & kings);
|
||||
|
||||
#ifdef USE_AVX512ICL
|
||||
if (threatened)
|
||||
{
|
||||
if constexpr (PutPiece)
|
||||
{
|
||||
dts->threatenedSqs |= threatened;
|
||||
dts->threateningSqs |= square_bb(s);
|
||||
}
|
||||
|
||||
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;
|
||||
if (!all_attackers)
|
||||
return; // Square s is threatened iff there's at least one attacker
|
||||
|
||||
dts->threatenedSqs |= square_bb(s);
|
||||
dts->threateningSqs |= all_attackers;
|
||||
|
||||
DirtyThreat dt_template{NO_PIECE, pc, Square(0), s, PutPiece};
|
||||
write_multiple_dirties<DirtyThreat::PcSqOffset, DirtyThreat::PcOffset>(*this, all_attackers,
|
||||
dt_template, dts);
|
||||
#else
|
||||
while (threatened)
|
||||
{
|
||||
Square threatenedSq = pop_lsb(threatened);
|
||||
@@ -1104,8 +1176,7 @@ void Position::update_piece_threats(Piece pc, Square s, DirtyThreats* const dts)
|
||||
|
||||
add_dirty_threat<PutPiece>(dts, pc, threatenedPc, s, threatenedSq);
|
||||
}
|
||||
|
||||
Bitboard sliders = (rookQueens & rAttacks) | (bishopQueens & bAttacks);
|
||||
#endif
|
||||
|
||||
if constexpr (ComputeRay)
|
||||
{
|
||||
@@ -1118,30 +1189,24 @@ void Position::update_piece_threats(Piece pc, Square s, DirtyThreats* const dts)
|
||||
const Bitboard discovered = ray & qAttacks & occupied;
|
||||
|
||||
assert(!more_than_one(discovered));
|
||||
if (discovered)
|
||||
if (discovered && (RayPassBB[sliderSq][s] & noRaysContaining) != noRaysContaining)
|
||||
{
|
||||
const Square threatenedSq = lsb(discovered);
|
||||
const Piece threatenedPc = piece_on(threatenedSq);
|
||||
add_dirty_threat<!PutPiece>(dts, slider, threatenedPc, sliderSq, threatenedSq);
|
||||
}
|
||||
|
||||
#ifndef USE_AVX512ICL // for ICL, direct threats were processed earlier (all_attackers)
|
||||
add_dirty_threat<PutPiece>(dts, slider, pc, sliderSq, s);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (sliders)
|
||||
{
|
||||
Square sliderSq = pop_lsb(sliders);
|
||||
Piece slider = piece_on(sliderSq);
|
||||
add_dirty_threat<PutPiece>(dts, slider, pc, sliderSq, s);
|
||||
}
|
||||
incoming_threats |= sliders;
|
||||
}
|
||||
|
||||
Bitboard incoming_threats =
|
||||
(PseudoAttacks[KNIGHT][s] & knights) | (attacks_bb<PAWN>(s, WHITE) & blackPawns)
|
||||
| (attacks_bb<PAWN>(s, BLACK) & whitePawns) | (PseudoAttacks[KING][s] & kings);
|
||||
|
||||
#ifndef USE_AVX512ICL
|
||||
while (incoming_threats)
|
||||
{
|
||||
Square srcSq = pop_lsb(incoming_threats);
|
||||
@@ -1152,6 +1217,7 @@ void Position::update_piece_threats(Piece pc, Square s, DirtyThreats* const dts)
|
||||
|
||||
add_dirty_threat<PutPiece>(dts, srcPc, pc, srcSq, s);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Helper used to do/undo a castling move. This is a bit
|
||||
|
||||
Reference in New Issue
Block a user