From e2aa1255707628aa1d70f13c88211724e34fa38e Mon Sep 17 00:00:00 2001 From: Shawn Xu Date: Tue, 8 Jul 2025 18:34:14 -0700 Subject: [PATCH] Consistent syntax for class members Currently, search.cpp uses three different syntax when accessing class member variables * thisThread object references. This was a remnant from when pos.this_thread() was necessary for thread-local variable access * this object references * implicit member variable access This PR aims to deprecate thisThread and standardize this syntax to implicit variable access, which is consistent with the rest of SF's codebase. closes https://github.com/official-stockfish/Stockfish/pull/6154 no functional change --- src/search.cpp | 152 ++++++++++++++++++++++--------------------------- 1 file changed, 69 insertions(+), 83 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index 1b5a2bbbc..fae3fc39f 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -258,8 +258,8 @@ void Search::Worker::iterative_deepening() { for (int i = 7; i > 0; --i) { (ss - i)->continuationHistory = - &this->continuationHistory[0][0][NO_PIECE][0]; // Use as a sentinel - (ss - i)->continuationCorrectionHistory = &this->continuationCorrectionHistory[NO_PIECE][0]; + &continuationHistory[0][0][NO_PIECE][0]; // Use as a sentinel + (ss - i)->continuationCorrectionHistory = &continuationCorrectionHistory[NO_PIECE][0]; (ss - i)->staticEval = VALUE_NONE; } @@ -586,7 +586,7 @@ Value Search::Worker::search( // Check if we have an upcoming move that draws by repetition if (!rootNode && alpha < VALUE_DRAW && pos.upcoming_repetition(ss->ply)) { - alpha = value_draw(this->nodes); + alpha = value_draw(nodes); if (alpha >= beta) return alpha; } @@ -612,29 +612,27 @@ Value Search::Worker::search( SearchedList quietsSearched; // Step 1. Initialize node - Worker* thisThread = this; - ss->inCheck = pos.checkers(); - priorCapture = pos.captured_piece(); - Color us = pos.side_to_move(); - ss->moveCount = 0; - bestValue = -VALUE_INFINITE; - maxValue = VALUE_INFINITE; + ss->inCheck = pos.checkers(); + priorCapture = pos.captured_piece(); + Color us = pos.side_to_move(); + ss->moveCount = 0; + bestValue = -VALUE_INFINITE; + maxValue = VALUE_INFINITE; // Check for the available remaining time if (is_mainthread()) - main_manager()->check_time(*thisThread); + main_manager()->check_time(*this); // Used to send selDepth info to GUI (selDepth counts from 1, ply from 0) - if (PvNode && thisThread->selDepth < ss->ply + 1) - thisThread->selDepth = ss->ply + 1; + if (PvNode && selDepth < ss->ply + 1) + selDepth = ss->ply + 1; if (!rootNode) { // Step 2. Check for aborted search and immediate draw if (threads.stop.load(std::memory_order_relaxed) || pos.is_draw(ss->ply) || ss->ply >= MAX_PLY) - return (ss->ply >= MAX_PLY && !ss->inCheck) ? evaluate(pos) - : value_draw(thisThread->nodes); + return (ss->ply >= MAX_PLY && !ss->inCheck) ? evaluate(pos) : value_draw(nodes); // Step 3. Mate distance pruning. Even if we mate at the next move our score // would be at best mate_in(ss->ply + 1), but if alpha is already bigger because @@ -663,9 +661,7 @@ Value Search::Worker::search( auto [ttHit, ttData, ttWriter] = tt.probe(posKey); // Need further processing of the saved data ss->ttHit = ttHit; - ttData.move = rootNode ? thisThread->rootMoves[thisThread->pvIdx].pv[0] - : ttHit ? ttData.move - : Move::none(); + ttData.move = rootNode ? rootMoves[pvIdx].pv[0] : ttHit ? ttData.move : Move::none(); ttData.value = ttHit ? value_from_tt(ttData.value, ss->ply, pos.rule50_count()) : VALUE_NONE; ss->ttPv = excludedMove ? ss->ttPv : PvNode || (ttHit && ttData.is_pv); ttCapture = ttData.move && pos.capture_stage(ttData.move); @@ -733,7 +729,7 @@ Value Search::Worker::search( if (err != TB::ProbeState::FAIL) { - thisThread->tbHits.fetch_add(1, std::memory_order_relaxed); + tbHits.fetch_add(1, std::memory_order_relaxed); int drawScore = tbConfig.useRule50 ? 1 : 0; @@ -770,7 +766,7 @@ Value Search::Worker::search( // Step 6. Static evaluation of the position Value unadjustedStaticEval = VALUE_NONE; - const auto correctionValue = correction_value(*thisThread, pos, ss); + const auto correctionValue = correction_value(*this, pos, ss); if (ss->inCheck) { // Skip early pruning when in check @@ -808,9 +804,9 @@ Value Search::Worker::search( if (((ss - 1)->currentMove).is_ok() && !(ss - 1)->inCheck && !priorCapture && !ttHit) { int bonus = std::clamp(-10 * int((ss - 1)->staticEval + ss->staticEval), -1858, 1492) + 661; - thisThread->mainHistory[~us][((ss - 1)->currentMove).from_to()] << bonus * 1057 / 1024; + mainHistory[~us][((ss - 1)->currentMove).from_to()] << bonus * 1057 / 1024; if (type_of(pos.piece_on(prevSq)) != PAWN && ((ss - 1)->currentMove).type_of() != PROMOTION) - thisThread->pawnHistory[pawn_structure_index(pos)][pos.piece_on(prevSq)][prevSq] + pawnHistory[pawn_structure_index(pos)][pos.piece_on(prevSq)][prevSq] << bonus * 1266 / 1024; } @@ -854,7 +850,7 @@ Value Search::Worker::search( // Step 9. Null move search with verification search if (cutNode && (ss - 1)->currentMove != Move::null() && eval >= beta && ss->staticEval >= beta - 19 * depth + 389 && !excludedMove && pos.non_pawn_material(us) - && ss->ply >= thisThread->nmpMinPly && !is_loss(beta)) + && ss->ply >= nmpMinPly && !is_loss(beta)) { assert(eval - beta >= 0); @@ -862,8 +858,8 @@ Value Search::Worker::search( Depth R = 7 + depth / 3; ss->currentMove = Move::null(); - ss->continuationHistory = &thisThread->continuationHistory[0][0][NO_PIECE][0]; - ss->continuationCorrectionHistory = &thisThread->continuationCorrectionHistory[NO_PIECE][0]; + ss->continuationHistory = &continuationHistory[0][0][NO_PIECE][0]; + ss->continuationCorrectionHistory = &continuationCorrectionHistory[NO_PIECE][0]; do_null_move(pos, st); @@ -874,18 +870,18 @@ Value Search::Worker::search( // Do not return unproven mate or TB scores if (nullValue >= beta && !is_win(nullValue)) { - if (thisThread->nmpMinPly || depth < 16) + if (nmpMinPly || depth < 16) return nullValue; - assert(!thisThread->nmpMinPly); // Recursive verification is not allowed + assert(!nmpMinPly); // Recursive verification is not allowed // Do verification search at high depths, with null move pruning disabled // until ply exceeds nmpMinPly. - thisThread->nmpMinPly = ss->ply + 3 * (depth - R) / 4; + nmpMinPly = ss->ply + 3 * (depth - R) / 4; Value v = search(pos, ss, beta - 1, beta, depth - R, false); - thisThread->nmpMinPly = 0; + nmpMinPly = 0; if (v >= beta) return nullValue; @@ -912,7 +908,7 @@ Value Search::Worker::search( { assert(probCutBeta < VALUE_INFINITE && probCutBeta > beta); - MovePicker mp(pos, ttData.move, probCutBeta - ss->staticEval, &thisThread->captureHistory); + MovePicker mp(pos, ttData.move, probCutBeta - ss->staticEval, &captureHistory); Depth probCutDepth = std::max(depth - 5, 0); while ((move = mp.next_move()) != Move::none()) @@ -930,9 +926,9 @@ Value Search::Worker::search( ss->currentMove = move; ss->continuationHistory = - &this->continuationHistory[ss->inCheck][true][movedPiece][move.to_sq()]; + &continuationHistory[ss->inCheck][true][movedPiece][move.to_sq()]; ss->continuationCorrectionHistory = - &this->continuationCorrectionHistory[movedPiece][move.to_sq()]; + &continuationCorrectionHistory[movedPiece][move.to_sq()]; // Perform a preliminary qsearch to verify that the move holds value = -qsearch(pos, ss + 1, -probCutBeta, -probCutBeta + 1); @@ -969,8 +965,8 @@ moves_loop: // When in check, search starts here (ss - 4)->continuationHistory, (ss - 5)->continuationHistory, (ss - 6)->continuationHistory}; - MovePicker mp(pos, ttData.move, depth, &thisThread->mainHistory, &thisThread->lowPlyHistory, - &thisThread->captureHistory, contHist, &thisThread->pawnHistory, ss->ply); + MovePicker mp(pos, ttData.move, depth, &mainHistory, &lowPlyHistory, &captureHistory, contHist, + &pawnHistory, ss->ply); value = bestValue; @@ -992,9 +988,7 @@ moves_loop: // When in check, search starts here // At root obey the "searchmoves" option and skip moves not listed in Root // Move List. In MultiPV mode we also skip PV moves that have been already // searched and those of lower "TB rank" if we are in a TB root position. - if (rootNode - && !std::count(thisThread->rootMoves.begin() + thisThread->pvIdx, - thisThread->rootMoves.begin() + thisThread->pvLast, move)) + if (rootNode && !std::count(rootMoves.begin() + pvIdx, rootMoves.begin() + pvLast, move)) continue; ss->moveCount = ++moveCount; @@ -1002,7 +996,7 @@ moves_loop: // When in check, search starts here if (rootNode && is_mainthread() && nodes > 10000000) { main_manager()->updates.onIter( - {depth, UCIEngine::move(move, pos.is_chess960()), moveCount + thisThread->pvIdx}); + {depth, UCIEngine::move(move, pos.is_chess960()), moveCount + pvIdx}); } if (PvNode) (ss + 1)->pv = nullptr; @@ -1041,8 +1035,7 @@ moves_loop: // When in check, search starts here if (capture || givesCheck) { Piece capturedPiece = pos.piece_on(move.to_sq()); - int captHist = - thisThread->captureHistory[movedPiece][move.to_sq()][type_of(capturedPiece)]; + int captHist = captureHistory[movedPiece][move.to_sq()][type_of(capturedPiece)]; // Futility pruning for captures if (!givesCheck && lmrDepth < 7 && !ss->inCheck) @@ -1071,16 +1064,15 @@ moves_loop: // When in check, search starts here } else { - int history = - (*contHist[0])[movedPiece][move.to_sq()] - + (*contHist[1])[movedPiece][move.to_sq()] - + thisThread->pawnHistory[pawn_structure_index(pos)][movedPiece][move.to_sq()]; + int history = (*contHist[0])[movedPiece][move.to_sq()] + + (*contHist[1])[movedPiece][move.to_sq()] + + pawnHistory[pawn_structure_index(pos)][movedPiece][move.to_sq()]; // Continuation history based pruning if (history < -4229 * depth) continue; - history += 68 * thisThread->mainHistory[us][move.from_to()] / 32; + history += 68 * mainHistory[us][move.from_to()] / 32; lmrDepth += history / 3388; @@ -1119,7 +1111,7 @@ moves_loop: // When in check, search starts here // and lower extension margins scale well. if (!rootNode && move == ttData.move && !excludedMove - && depth >= 6 - (thisThread->completedDepth > 27) + ss->ttPv && is_valid(ttData.value) + && depth >= 6 - (completedDepth > 27) + ss->ttPv && is_valid(ttData.value) && !is_decisive(ttData.value) && (ttData.bound & BOUND_LOWER) && ttData.depth >= depth - 3) { @@ -1134,10 +1126,9 @@ moves_loop: // When in check, search starts here { int corrValAdj = std::abs(correctionValue) / 248400; int doubleMargin = -4 + 244 * PvNode - 206 * !ttCapture - corrValAdj - - 997 * ttMoveHistory / 131072 - - (ss->ply > thisThread->rootDepth) * 47; + - 997 * ttMoveHistory / 131072 - (ss->ply > rootDepth) * 47; int tripleMargin = 84 + 269 * PvNode - 253 * !ttCapture + 91 * ss->ttPv - corrValAdj - - (ss->ply * 2 > thisThread->rootDepth * 3) * 54; + - (ss->ply * 2 > rootDepth * 3) * 54; extension = 1 + (value < singularBeta - doubleMargin) + (value < singularBeta - tripleMargin); @@ -1180,9 +1171,9 @@ moves_loop: // When in check, search starts here // Update the current move (this must be done after singular extension search) ss->currentMove = move; ss->continuationHistory = - &thisThread->continuationHistory[ss->inCheck][capture][movedPiece][move.to_sq()]; + &continuationHistory[ss->inCheck][capture][movedPiece][move.to_sq()]; ss->continuationCorrectionHistory = - &thisThread->continuationCorrectionHistory[movedPiece][move.to_sq()]; + &continuationCorrectionHistory[movedPiece][move.to_sq()]; uint64_t nodeCount = rootNode ? uint64_t(nodes) : 0; // Decrease reduction for PvNodes (*Scaler) @@ -1215,11 +1206,10 @@ moves_loop: // When in check, search starts here r -= 2006; if (capture) - ss->statScore = - 826 * int(PieceValue[pos.captured_piece()]) / 128 - + thisThread->captureHistory[movedPiece][move.to_sq()][type_of(pos.captured_piece())]; + ss->statScore = 826 * int(PieceValue[pos.captured_piece()]) / 128 + + captureHistory[movedPiece][move.to_sq()][type_of(pos.captured_piece())]; else - ss->statScore = 2 * thisThread->mainHistory[us][move.from_to()] + ss->statScore = 2 * mainHistory[us][move.from_to()] + (*contHist[0])[movedPiece][move.to_sq()] + (*contHist[1])[movedPiece][move.to_sq()]; @@ -1284,7 +1274,7 @@ moves_loop: // When in check, search starts here (ss + 1)->pv[0] = Move::none(); // Extend move from transposition table if we are about to dive into qsearch. - if (move == ttData.move && thisThread->rootDepth > 8) + if (move == ttData.move && rootDepth > 8) newDepth = std::max(newDepth, 1); value = -search(pos, ss + 1, -beta, -alpha, newDepth, false); @@ -1304,8 +1294,7 @@ moves_loop: // When in check, search starts here if (rootNode) { - RootMove& rm = - *std::find(thisThread->rootMoves.begin(), thisThread->rootMoves.end(), move); + RootMove& rm = *std::find(rootMoves.begin(), rootMoves.end(), move); rm.effort += nodes - nodeCount; @@ -1320,7 +1309,7 @@ moves_loop: // When in check, search starts here if (moveCount == 1 || value > alpha) { rm.score = rm.uciScore = value; - rm.selDepth = thisThread->selDepth; + rm.selDepth = selDepth; rm.scoreLowerbound = rm.scoreUpperbound = false; if (value >= beta) @@ -1344,8 +1333,8 @@ moves_loop: // When in check, search starts here // We record how often the best move has been changed in each iteration. // This information is used for time management. In MultiPV mode, // we must take care to only do this for the first PV line. - if (moveCount > 1 && !thisThread->pvIdx) - ++thisThread->bestMoveChanges; + if (moveCount > 1 && !pvIdx) + ++bestMoveChanges; } else // All other moves but the PV, are set to the lowest value: this @@ -1356,8 +1345,8 @@ moves_loop: // When in check, search starts here // In case we have an alternative move equal in eval to the current bestmove, // promote it to bestmove by pretending it just exceeds alpha (but not beta). - int inc = (value == bestValue && ss->ply + 2 >= thisThread->rootDepth - && (int(nodes) & 15) == 0 && !is_win(std::abs(value) + 1)); + int inc = (value == bestValue && ss->ply + 2 >= rootDepth && (int(nodes) & 15) == 0 + && !is_win(std::abs(value) + 1)); if (value + inc > bestValue) { @@ -1439,11 +1428,10 @@ moves_loop: // When in check, search starts here update_continuation_histories(ss - 1, pos.piece_on(prevSq), prevSq, scaledBonus * 412 / 32768); - thisThread->mainHistory[~us][((ss - 1)->currentMove).from_to()] - << scaledBonus * 203 / 32768; + mainHistory[~us][((ss - 1)->currentMove).from_to()] << scaledBonus * 203 / 32768; if (type_of(pos.piece_on(prevSq)) != PAWN && ((ss - 1)->currentMove).type_of() != PROMOTION) - thisThread->pawnHistory[pawn_structure_index(pos)][pos.piece_on(prevSq)][prevSq] + pawnHistory[pawn_structure_index(pos)][pos.piece_on(prevSq)][prevSq] << scaledBonus * 1040 / 32768; } @@ -1452,7 +1440,7 @@ moves_loop: // When in check, search starts here { Piece capturedPiece = pos.captured_piece(); assert(capturedPiece != NO_PIECE); - thisThread->captureHistory[pos.piece_on(prevSq)][prevSq][type_of(capturedPiece)] << 1080; + captureHistory[pos.piece_on(prevSq)][prevSq][type_of(capturedPiece)] << 1080; } if (PvNode) @@ -1465,7 +1453,7 @@ moves_loop: // When in check, search starts here // Write gathered information in transposition table. Note that the // static evaluation is saved as it was before correction history. - if (!excludedMove && !(rootNode && thisThread->pvIdx)) + if (!excludedMove && !(rootNode && pvIdx)) ttWriter.write(posKey, value_to_tt(bestValue, ss->ply), ss->ttPv, bestValue >= beta ? BOUND_LOWER : PvNode && bestMove ? BOUND_EXACT @@ -1480,7 +1468,7 @@ moves_loop: // When in check, search starts here { auto bonus = std::clamp(int(bestValue - ss->staticEval) * depth / 8, -CORRECTION_HISTORY_LIMIT / 4, CORRECTION_HISTORY_LIMIT / 4); - update_correction_history(pos, ss, *thisThread, bonus); + update_correction_history(pos, ss, *this, bonus); } assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE); @@ -1507,7 +1495,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta) // Check if we have an upcoming move that draws by repetition if (alpha < VALUE_DRAW && pos.upcoming_repetition(ss->ply)) { - alpha = value_draw(this->nodes); + alpha = value_draw(nodes); if (alpha >= beta) return alpha; } @@ -1528,14 +1516,13 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta) ss->pv[0] = Move::none(); } - Worker* thisThread = this; - bestMove = Move::none(); - ss->inCheck = pos.checkers(); - moveCount = 0; + bestMove = Move::none(); + ss->inCheck = pos.checkers(); + moveCount = 0; // Used to send selDepth info to GUI (selDepth counts from 1, ply from 0) - if (PvNode && thisThread->selDepth < ss->ply + 1) - thisThread->selDepth = ss->ply + 1; + if (PvNode && selDepth < ss->ply + 1) + selDepth = ss->ply + 1; // Step 2. Check for an immediate draw or maximum ply reached if (pos.is_draw(ss->ply) || ss->ply >= MAX_PLY) @@ -1564,7 +1551,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta) bestValue = futilityBase = -VALUE_INFINITE; else { - const auto correctionValue = correction_value(*thisThread, pos, ss); + const auto correctionValue = correction_value(*this, pos, ss); if (ss->ttHit) { @@ -1614,8 +1601,8 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta) // Initialize a MovePicker object for the current position, and prepare to search // the moves. We presently use two stages of move generator in quiescence search: // captures, or evasions only when in check. - MovePicker mp(pos, ttData.move, DEPTH_QS, &thisThread->mainHistory, &thisThread->lowPlyHistory, - &thisThread->captureHistory, contHist, &thisThread->pawnHistory, ss->ply); + MovePicker mp(pos, ttData.move, DEPTH_QS, &mainHistory, &lowPlyHistory, &captureHistory, + contHist, &pawnHistory, ss->ply); // Step 5. Loop through all pseudo-legal moves until no moves remain or a beta // cutoff occurs. @@ -1663,8 +1650,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta) // Continuation history based pruning if (!capture && (*contHist[0])[pos.moved_piece(move)][move.to_sq()] - + thisThread->pawnHistory[pawn_structure_index(pos)][pos.moved_piece(move)] - [move.to_sq()] + + pawnHistory[pawn_structure_index(pos)][pos.moved_piece(move)][move.to_sq()] <= 6218) continue; @@ -1681,9 +1667,9 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta) // Update the current move ss->currentMove = move; ss->continuationHistory = - &thisThread->continuationHistory[ss->inCheck][capture][movedPiece][move.to_sq()]; + &continuationHistory[ss->inCheck][capture][movedPiece][move.to_sq()]; ss->continuationCorrectionHistory = - &thisThread->continuationCorrectionHistory[movedPiece][move.to_sq()]; + &continuationCorrectionHistory[movedPiece][move.to_sq()]; value = -qsearch(pos, ss + 1, -beta, -alpha); undo_move(pos, move);