mirror of
https://github.com/official-stockfish/Stockfish.git
synced 2026-07-22 12:47:08 +00:00
prefetch the TT entry as soon as the move is known
Worker::do_move computes the successor hash key via the new Position::key_after(m) and prefetches the TT entry one full do_move earlier than the existing prefetch in Position::do_move. key_after does not model castling, en passant or promotion keys exactly; for rare moves the prefetch lands on an unused line. `key_after` has been around since 2014 (https://github.com/official-stockfish/Stockfish/commit/82d065b0) and was removed in (https://github.com/official-stockfish/Stockfish/pull/5770). Adding back `prefetch_key` helps in common, normal moves at the cost of extra compute. Speedup (PGO vs PGO, interleaved paired bench, n=48 pairs, Apple M2 Pro / apple-silicon): +0.69% [0.47, 0.91] Passed STC: https://tests.stockfishchess.org/tests/view/6a291f8d7c758d82accea17f LLR: 4.24 (-2.94,2.94) <0.00,2.00> Total: 473504 W: 121250 L: 120228 D: 232026 Ptnml(0-2): 1112, 51137, 131251, 52121, 1131 No functional change closes https://github.com/official-stockfish/Stockfish/pull/6911 No functional change
This commit is contained in:
committed by
Joost VandeVondele
parent
31e89adf70
commit
6f97594eda
@@ -62,6 +62,7 @@ Clemens L. (rn5f107s2)
|
|||||||
Cody Ho (aesrentai)
|
Cody Ho (aesrentai)
|
||||||
CSTENTOR
|
CSTENTOR
|
||||||
Dale Weiler (graphitemaster)
|
Dale Weiler (graphitemaster)
|
||||||
|
Dalton Hanaway (dhanaway)
|
||||||
Daniel Axtens (daxtens)
|
Daniel Axtens (daxtens)
|
||||||
Daniel Dugovic (ddugovic)
|
Daniel Dugovic (ddugovic)
|
||||||
Daniel Monroe (daniel-monroe)
|
Daniel Monroe (daniel-monroe)
|
||||||
|
|||||||
@@ -1315,6 +1315,21 @@ void Position::update_piece_threats(Piece pc,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Key Position::prefetch_key(Move m) const {
|
||||||
|
Square from = m.from_sq();
|
||||||
|
Square to = m.to_sq();
|
||||||
|
Piece pc = piece_on(from);
|
||||||
|
Piece captured = piece_on(to);
|
||||||
|
Key k = st->key ^ Zobrist::side;
|
||||||
|
|
||||||
|
k ^= Zobrist::psq[captured][to] ^ Zobrist::psq[pc][to] ^ Zobrist::psq[pc][from];
|
||||||
|
|
||||||
|
if (captured || type_of(pc) == PAWN)
|
||||||
|
return k;
|
||||||
|
|
||||||
|
return adjust_key50<true>(k);
|
||||||
|
}
|
||||||
|
|
||||||
// Helper used to do/undo a castling move. This is a bit
|
// Helper used to do/undo a castling move. This is a bit
|
||||||
// tricky in Chess960 where from/to squares can overlap.
|
// tricky in Chess960 where from/to squares can overlap.
|
||||||
template<bool Do>
|
template<bool Do>
|
||||||
|
|||||||
+4
-1
@@ -160,6 +160,7 @@ class Position {
|
|||||||
|
|
||||||
// Accessing hash keys
|
// Accessing hash keys
|
||||||
Key key() const;
|
Key key() const;
|
||||||
|
Key prefetch_key(Move m) const;
|
||||||
Key material_key() const;
|
Key material_key() const;
|
||||||
Key pawn_key() const;
|
Key pawn_key() const;
|
||||||
Key minor_piece_key() const;
|
Key minor_piece_key() const;
|
||||||
@@ -211,6 +212,7 @@ class Position {
|
|||||||
Square& rto,
|
Square& rto,
|
||||||
DirtyThreats* const dts = nullptr,
|
DirtyThreats* const dts = nullptr,
|
||||||
DirtyPiece* const dp = nullptr);
|
DirtyPiece* const dp = nullptr);
|
||||||
|
template<bool AfterMove = false>
|
||||||
Key adjust_key50(Key k) const;
|
Key adjust_key50(Key k) const;
|
||||||
|
|
||||||
// Data members
|
// Data members
|
||||||
@@ -317,8 +319,9 @@ inline Bitboard Position::check_squares(PieceType pt) const { return st->checkSq
|
|||||||
|
|
||||||
inline Key Position::key() const { return adjust_key50(st->key); }
|
inline Key Position::key() const { return adjust_key50(st->key); }
|
||||||
|
|
||||||
|
template<bool AfterMove>
|
||||||
inline Key Position::adjust_key50(Key k) const {
|
inline Key Position::adjust_key50(Key k) const {
|
||||||
return st->rule50 < 14 ? k : k ^ make_key((st->rule50 - 14) / 8);
|
return st->rule50 < 14 - AfterMove ? k : k ^ make_key((st->rule50 - (14 - AfterMove)) / 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Key Position::pawn_key() const { return st->pawnKey; }
|
inline Key Position::pawn_key() const { return st->pawnKey; }
|
||||||
|
|||||||
@@ -634,6 +634,10 @@ void Search::Worker::do_move(Position& pos, const Move move, StateInfo& st, Stac
|
|||||||
|
|
||||||
void Search::Worker::do_move(
|
void Search::Worker::do_move(
|
||||||
Position& pos, const Move move, StateInfo& st, const bool givesCheck, Stack* const ss) {
|
Position& pos, const Move move, StateInfo& st, const bool givesCheck, Stack* const ss) {
|
||||||
|
// prefetch_key does not model castling, en passant or promotion keys
|
||||||
|
// exactly; for rare moves the prefetch lands on an unused line.
|
||||||
|
prefetch(tt.first_entry(pos.prefetch_key(move)));
|
||||||
|
|
||||||
bool capture = pos.capture_stage(move);
|
bool capture = pos.capture_stage(move);
|
||||||
++nodes;
|
++nodes;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user