mirror of
https://github.com/HChaZZY/Stockfish.git
synced 2025-12-06 10:53:50 +08:00
prefetch in do_move()
this allows removing Position::key_after() STC LLR: 2.93 (-2.94,2.94) <-1.75,0.25> Total: 24960 W: 6556 L: 6336 D: 12068 Ptnml(0-2): 59, 2554, 7056, 2730, 81 LTC LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 115080 W: 29319 L: 29204 D: 56557 Ptnml(0-2): 51, 10736, 35864, 10825, 64 STC with 2MB hash LLR: 3.04 (-2.94,2.94) <-1.75,0.25> Total: 182176 W: 46998 L: 46932 D: 88246 Ptnml(0-2): 526, 19711, 50544, 19785, 522 LTC with 8MB hash LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 441180 W: 111557 L: 111746 D: 217877 Ptnml(0-2): 229, 39698, 140929, 39501, 233 closes https://github.com/official-stockfish/Stockfish/pull/5770 bench: 1379150
This commit is contained in:
committed by
Joost VandeVondele
parent
c085670b84
commit
aaafaaecf2
@@ -689,7 +689,12 @@ bool Position::gives_check(Move m) const {
|
||||
// Makes a move, and saves all information necessary
|
||||
// to a StateInfo object. The move is assumed to be legal. Pseudo-legal
|
||||
// moves should be filtered out before this function is called.
|
||||
void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
|
||||
// If a pointer to the TT table is passed, the entry for the new position
|
||||
// will be prefetched
|
||||
void Position::do_move(Move m,
|
||||
StateInfo& newSt,
|
||||
bool givesCheck,
|
||||
const TranspositionTable* tt = nullptr) {
|
||||
|
||||
assert(m.is_ok());
|
||||
assert(&newSt != st);
|
||||
@@ -887,11 +892,13 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
|
||||
st->minorPieceKey ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
|
||||
}
|
||||
|
||||
// Set capture piece
|
||||
st->capturedPiece = captured;
|
||||
|
||||
// Update the key with the final value
|
||||
st->key = k;
|
||||
if (tt)
|
||||
prefetch(tt->first_entry(key()));
|
||||
|
||||
// Set capture piece
|
||||
st->capturedPiece = captured;
|
||||
|
||||
// Calculate checkers bitboard (if move gives check)
|
||||
st->checkersBB = givesCheck ? attackers_to(square<KING>(them)) & pieces(us) : 0;
|
||||
@@ -1069,23 +1076,6 @@ void Position::undo_null_move() {
|
||||
}
|
||||
|
||||
|
||||
// Computes the new hash key after the given move. Needed
|
||||
// for speculative prefetch. It doesn't recognize special moves like castling,
|
||||
// en passant and promotions.
|
||||
Key Position::key_after(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];
|
||||
|
||||
return (captured || type_of(pc) == PAWN) ? k : adjust_key50<true>(k);
|
||||
}
|
||||
|
||||
|
||||
// Tests if the SEE (Static Exchange Evaluation)
|
||||
// value of move is greater or equal to the given threshold. We'll use an
|
||||
// algorithm similar to alpha-beta pruning with a null window.
|
||||
|
||||
@@ -141,8 +141,8 @@ class Position {
|
||||
Piece captured_piece() const;
|
||||
|
||||
// Doing and undoing moves
|
||||
void do_move(Move m, StateInfo& newSt);
|
||||
void do_move(Move m, StateInfo& newSt, bool givesCheck);
|
||||
void do_move(Move m, StateInfo& newSt, const TranspositionTable* tt);
|
||||
void do_move(Move m, StateInfo& newSt, bool givesCheck, const TranspositionTable* tt);
|
||||
void undo_move(Move m);
|
||||
void do_null_move(StateInfo& newSt, const TranspositionTable& tt);
|
||||
void undo_null_move();
|
||||
@@ -152,7 +152,6 @@ class Position {
|
||||
|
||||
// Accessing hash keys
|
||||
Key key() const;
|
||||
Key key_after(Move m) const;
|
||||
Key material_key() const;
|
||||
Key pawn_key() const;
|
||||
Key major_piece_key() const;
|
||||
@@ -369,7 +368,9 @@ inline void Position::move_piece(Square from, Square to) {
|
||||
board[to] = pc;
|
||||
}
|
||||
|
||||
inline void Position::do_move(Move m, StateInfo& newSt) { do_move(m, newSt, gives_check(m)); }
|
||||
inline void Position::do_move(Move m, StateInfo& newSt, const TranspositionTable* tt = nullptr) {
|
||||
do_move(m, newSt, gives_check(m), tt);
|
||||
}
|
||||
|
||||
inline StateInfo* Position::state() const { return st; }
|
||||
|
||||
|
||||
@@ -872,17 +872,16 @@ Value Search::Worker::search(
|
||||
|
||||
assert(pos.capture_stage(move));
|
||||
|
||||
// Prefetch the TT entry for the resulting position
|
||||
prefetch(tt.first_entry(pos.key_after(move)));
|
||||
movedPiece = pos.moved_piece(move);
|
||||
|
||||
pos.do_move(move, st, &tt);
|
||||
thisThread->nodes.fetch_add(1, std::memory_order_relaxed);
|
||||
|
||||
ss->currentMove = move;
|
||||
ss->continuationHistory =
|
||||
&this->continuationHistory[ss->inCheck][true][pos.moved_piece(move)][move.to_sq()];
|
||||
&this->continuationHistory[ss->inCheck][true][movedPiece][move.to_sq()];
|
||||
ss->continuationCorrectionHistory =
|
||||
&this->continuationCorrectionHistory[pos.moved_piece(move)][move.to_sq()];
|
||||
|
||||
thisThread->nodes.fetch_add(1, std::memory_order_relaxed);
|
||||
pos.do_move(move, st);
|
||||
&this->continuationCorrectionHistory[movedPiece][move.to_sq()];
|
||||
|
||||
// Perform a preliminary qsearch to verify that the move holds
|
||||
value = -qsearch<NonPV>(pos, ss + 1, -probCutBeta, -probCutBeta + 1);
|
||||
@@ -1118,12 +1117,13 @@ moves_loop: // When in check, search starts here
|
||||
extension = 1;
|
||||
}
|
||||
|
||||
// Step 16. Make the move
|
||||
pos.do_move(move, st, givesCheck, &tt);
|
||||
thisThread->nodes.fetch_add(1, std::memory_order_relaxed);
|
||||
|
||||
// Add extension to new depth
|
||||
newDepth += extension;
|
||||
|
||||
// Speculative prefetch as early as possible
|
||||
prefetch(tt.first_entry(pos.key_after(move)));
|
||||
|
||||
// Update the current move (this must be done after singular extension search)
|
||||
ss->currentMove = move;
|
||||
ss->continuationHistory =
|
||||
@@ -1132,10 +1132,6 @@ moves_loop: // When in check, search starts here
|
||||
&thisThread->continuationCorrectionHistory[movedPiece][move.to_sq()];
|
||||
uint64_t nodeCount = rootNode ? uint64_t(nodes) : 0;
|
||||
|
||||
// Step 16. Make the move
|
||||
thisThread->nodes.fetch_add(1, std::memory_order_relaxed);
|
||||
pos.do_move(move, st, givesCheck);
|
||||
|
||||
// These reduction adjustments have proven non-linear scaling.
|
||||
// They are optimized to time controls of 180 + 1.8 and longer,
|
||||
// so changing them or adding conditions that are similar requires
|
||||
@@ -1637,20 +1633,19 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta)
|
||||
continue;
|
||||
}
|
||||
|
||||
// Speculative prefetch as early as possible
|
||||
prefetch(tt.first_entry(pos.key_after(move)));
|
||||
// Step 7. Make and search the move
|
||||
Piece movedPiece = pos.moved_piece(move);
|
||||
|
||||
pos.do_move(move, st, givesCheck, &tt);
|
||||
thisThread->nodes.fetch_add(1, std::memory_order_relaxed);
|
||||
|
||||
// Update the current move
|
||||
ss->currentMove = move;
|
||||
ss->continuationHistory =
|
||||
&thisThread
|
||||
->continuationHistory[ss->inCheck][capture][pos.moved_piece(move)][move.to_sq()];
|
||||
&thisThread->continuationHistory[ss->inCheck][capture][movedPiece][move.to_sq()];
|
||||
ss->continuationCorrectionHistory =
|
||||
&thisThread->continuationCorrectionHistory[pos.moved_piece(move)][move.to_sq()];
|
||||
&thisThread->continuationCorrectionHistory[movedPiece][move.to_sq()];
|
||||
|
||||
// Step 7. Make and search the move
|
||||
thisThread->nodes.fetch_add(1, std::memory_order_relaxed);
|
||||
pos.do_move(move, st, givesCheck);
|
||||
value = -qsearch<nodeType>(pos, ss + 1, -beta, -alpha);
|
||||
pos.undo_move(move);
|
||||
|
||||
@@ -2148,7 +2143,7 @@ bool RootMove::extract_ponder_from_tt(const TranspositionTable& tt, Position& po
|
||||
if (pv[0] == Move::none())
|
||||
return false;
|
||||
|
||||
pos.do_move(pv[0], st);
|
||||
pos.do_move(pv[0], st, &tt);
|
||||
|
||||
auto [ttHit, ttData, ttWriter] = tt.probe(pos.key());
|
||||
if (ttHit)
|
||||
|
||||
Reference in New Issue
Block a user