From d3fc1d835e5144cc98d6a7658fb8cfd9370792f1 Mon Sep 17 00:00:00 2001 From: Disservin Date: Wed, 10 Apr 2024 23:10:07 +0200 Subject: [PATCH] Refactor elapsed time checks in search Small improvement of the elapsed time usage in search, makes the code easier to read overall. Also Search::Worker::iterative_deepening() now only checks the elapsed time once, instead of 3 times in a row. Non Regression STC: https://tests.stockfishchess.org/tests/view/6617005d5a4693796d965c3c LLR: 2.97 (-2.94,2.94) <-1.75,0.25> Total: 61024 W: 16002 L: 15806 D: 29216 Ptnml(0-2): 243, 6874, 16102, 7030, 263 closes https://github.com/official-stockfish/Stockfish/pull/5163 No functional change --- src/search.cpp | 28 +++++++++++++++------------- src/search.h | 2 ++ src/timeman.cpp | 3 --- src/timeman.h | 6 ++++-- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index 0eb0f45e..00636865 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -340,7 +340,7 @@ void Search::Worker::iterative_deepening() { // When failing high/low give some update (without cluttering // the UI) before a re-search. if (mainThread && multiPV == 1 && (bestValue <= alpha || bestValue >= beta) - && mainThread->tm.elapsed(threads.nodes_searched()) > 3000) + && elapsed() > 3000) main_manager()->pv(*this, threads, tt, rootDepth); // In case of failing low/high increase aspiration window and @@ -371,8 +371,7 @@ void Search::Worker::iterative_deepening() { std::stable_sort(rootMoves.begin() + pvFirst, rootMoves.begin() + pvIdx + 1); if (mainThread - && (threads.stop || pvIdx + 1 == multiPV - || mainThread->tm.elapsed(threads.nodes_searched()) > 3000) + && (threads.stop || pvIdx + 1 == multiPV || elapsed() > 3000) // A thread that aborted search can have mated-in/TB-loss PV and score // that cannot be trusted, i.e. it can be delayed or refuted if we would have // had time to fully search other root-moves. Thus we suppress this output and @@ -448,13 +447,14 @@ void Search::Worker::iterative_deepening() { if (rootMoves.size() == 1) totalTime = std::min(500.0, totalTime); - if (completedDepth >= 10 && nodesEffort >= 97 - && mainThread->tm.elapsed(threads.nodes_searched()) > totalTime * 0.739 + auto elapsedTime = elapsed(); + + if (completedDepth >= 10 && nodesEffort >= 97 && elapsedTime > totalTime * 0.739 && !mainThread->ponder) threads.stop = true; // Stop the search if we have exceeded the totalTime - if (mainThread->tm.elapsed(threads.nodes_searched()) > totalTime) + if (elapsedTime > totalTime) { // If we are allowed to ponder do not stop the search now but // keep pondering until the GUI sends "ponderhit" or "stop". @@ -464,9 +464,7 @@ void Search::Worker::iterative_deepening() { threads.stop = true; } else - threads.increaseDepth = - mainThread->ponder - || mainThread->tm.elapsed(threads.nodes_searched()) <= totalTime * 0.506; + threads.increaseDepth = mainThread->ponder || elapsedTime <= totalTime * 0.506; } mainThread->iterValue[iterIdx] = bestValue; @@ -928,8 +926,7 @@ moves_loop: // When in check, search starts here ss->moveCount = ++moveCount; - if (rootNode && is_mainthread() - && main_manager()->tm.elapsed(threads.nodes_searched()) > 3000) + if (rootNode && is_mainthread() && elapsed() > 3000) { main_manager()->updates.onIter( {depth, UCIEngine::move(move, pos.is_chess960()), moveCount + thisThread->pvIdx}); @@ -1631,6 +1628,11 @@ Depth Search::Worker::reduction(bool i, Depth d, int mn, int delta) { return (reductionScale + 1123 - delta * 832 / rootDelta) / 1024 + (!i && reductionScale > 1025); } +TimePoint Search::Worker::elapsed() const { + return main_manager()->tm.elapsed([this]() { return threads.nodes_searched(); }); +} + + namespace { // Adjusts a mate or TB score from "plies to mate from the root" // to "plies to mate from the current position". Standard scores are unchanged. @@ -1845,7 +1847,7 @@ void SearchManager::check_time(Search::Worker& worker) { static TimePoint lastInfoTime = now(); - TimePoint elapsed = tm.elapsed(worker.threads.nodes_searched()); + TimePoint elapsed = tm.elapsed([&worker]() { return worker.threads.nodes_searched(); }); TimePoint tick = worker.limits.startTime + elapsed; if (tick - lastInfoTime >= 1000) @@ -1877,7 +1879,7 @@ void SearchManager::pv(const Search::Worker& worker, const auto& rootMoves = worker.rootMoves; const auto& pos = worker.rootPos; size_t pvIdx = worker.pvIdx; - TimePoint time = tm.elapsed(nodes) + 1; + TimePoint time = tm.elapsed([nodes]() { return nodes; }) + 1; size_t multiPV = std::min(size_t(worker.options["MultiPV"]), rootMoves.size()); uint64_t tbHits = threads.tb_hits() + (worker.tbConfig.rootInTB ? rootMoves.size() : 0); diff --git a/src/search.h b/src/search.h index d30a06fe..3ceaf5dd 100644 --- a/src/search.h +++ b/src/search.h @@ -275,6 +275,8 @@ class Worker { return static_cast(manager.get()); } + TimePoint elapsed() const; + LimitsType limits; size_t pvIdx, pvLast; diff --git a/src/timeman.cpp b/src/timeman.cpp index 229ff3e9..c651745f 100644 --- a/src/timeman.cpp +++ b/src/timeman.cpp @@ -30,9 +30,6 @@ namespace Stockfish { TimePoint TimeManagement::optimum() const { return optimumTime; } TimePoint TimeManagement::maximum() const { return maximumTime; } -TimePoint TimeManagement::elapsed(size_t nodes) const { - return useNodesTime ? TimePoint(nodes) : now() - startTime; -} void TimeManagement::clear() { availableNodes = 0; // When in 'nodes as time' mode diff --git a/src/timeman.h b/src/timeman.h index b07712a2..35c3cfc0 100644 --- a/src/timeman.h +++ b/src/timeman.h @@ -19,7 +19,6 @@ #ifndef TIMEMAN_H_INCLUDED #define TIMEMAN_H_INCLUDED -#include #include #include "misc.h" @@ -41,7 +40,10 @@ class TimeManagement { TimePoint optimum() const; TimePoint maximum() const; - TimePoint elapsed(std::size_t nodes) const; + template + TimePoint elapsed(FUNC nodes) const { + return useNodesTime ? TimePoint(nodes()) : now() - startTime; + } void clear(); void advance_nodes_time(std::int64_t nodes);