From 3c62ad7e077a5ed0ea7b55422e03e7316dcbce7e Mon Sep 17 00:00:00 2001 From: xoto10 <23479932+xoto10@users.noreply.github.com> Date: Tue, 28 May 2024 19:40:40 +0100 Subject: [PATCH] Add compensation factor to adjust extra time according to time control As stockfish nets and search evolve, the existing time control appears to give too little time at STC, roughly correct at LTC, and too little at VLTC+. This change adds an adjustment to the optExtra calculation. This adjustment is easy to retune and refine, so it should be easier to keep up-to-date than the more complex calculations used for optConstant and optScale. Passed STC 10+0.1: LLR: 2.93 (-2.94,2.94) <0.00,2.00> Total: 169568 W: 43803 L: 43295 D: 82470 Ptnml(0-2): 485, 19679, 44055, 19973, 592 https://tests.stockfishchess.org/tests/view/66531865a86388d5e27da9fa Yellow LTC 60+0.6: LLR: -2.94 (-2.94,2.94) <0.50,2.50> Total: 209970 W: 53087 L: 52914 D: 103969 Ptnml(0-2): 91, 19652, 65314, 19849, 79 https://tests.stockfishchess.org/tests/view/6653e38ba86388d5e27daaa0 Passed VLTC 180+1.8 : LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 85618 W: 21735 L: 21342 D: 42541 Ptnml(0-2): 15, 8267, 25848, 8668, 11 https://tests.stockfishchess.org/tests/view/6655131da86388d5e27db95f closes https://github.com/official-stockfish/Stockfish/pull/5297 Bench: 1212167 --- src/search.cpp | 2 +- src/search.h | 1 + src/thread.cpp | 1 + src/timeman.cpp | 14 ++++++++++++-- src/timeman.h | 8 ++++++-- 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index 5e9f647636d..ec4ae79d508 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -161,7 +161,7 @@ void Search::Worker::start_searching() { } main_manager()->tm.init(limits, rootPos.side_to_move(), rootPos.game_ply(), options, - main_manager()->originalPly); + main_manager()->originalPly, main_manager()->originalTimeAdjust); tt.new_search(); if (rootMoves.empty()) diff --git a/src/search.h b/src/search.h index a61f253c005..7cff10d5590 100644 --- a/src/search.h +++ b/src/search.h @@ -208,6 +208,7 @@ class SearchManager: public ISearchManager { Depth depth) const; Stockfish::TimeManagement tm; + double originalTimeAdjust; int originalPly; int callsCnt; std::atomic_bool ponder; diff --git a/src/thread.cpp b/src/thread.cpp index 5893f4b6d07..71134ead6ea 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -217,6 +217,7 @@ void ThreadPool::clear() { main_manager()->bestPreviousScore = VALUE_INFINITE; main_manager()->bestPreviousAverageScore = VALUE_INFINITE; main_manager()->originalPly = -1; + main_manager()->originalTimeAdjust = -1; main_manager()->previousTimeReduction = 1.0; main_manager()->tm.clear(); } diff --git a/src/timeman.cpp b/src/timeman.cpp index f389e082d8e..f6ca298a82f 100644 --- a/src/timeman.cpp +++ b/src/timeman.cpp @@ -44,8 +44,12 @@ void TimeManagement::advance_nodes_time(std::int64_t nodes) { // the bounds of time allowed for the current game ply. We currently support: // 1) x basetime (+ z increment) // 2) x moves in y seconds (+ z increment) -void TimeManagement::init( - Search::LimitsType& limits, Color us, int ply, const OptionsMap& options, int& originalPly) { +void TimeManagement::init(Search::LimitsType& limits, + Color us, + int ply, + const OptionsMap& options, + int& originalPly, + double& originalTimeAdjust) { TimePoint npmsec = TimePoint(options["nodestime"]); // If we have no time, we don't need to fully initialize TM. @@ -100,6 +104,10 @@ void TimeManagement::init( TimePoint timeLeft = std::max(TimePoint(1), limits.time[us] + limits.inc[us] * (mtg - 1) - moveOverhead * (2 + mtg)); + // Extra time according to timeLeft + if (originalTimeAdjust < 0) + originalTimeAdjust = 0.2078 + 0.1623 * std::log10(timeLeft); + // x basetime (+ z increment) // If there is a healthy increment, timeLeft can exceed the actual available // game time for the current move, so also cap to a percentage of available game time. @@ -109,6 +117,7 @@ void TimeManagement::init( double optExtra = scaledInc < 500 ? 1.0 : 1.13; if (ply - originalPly < 2) optExtra *= 0.95; + optExtra *= originalTimeAdjust; // Calculate time constants based on current time left. double logTimeInSec = std::log10(scaledTime / 1000.0); @@ -118,6 +127,7 @@ void TimeManagement::init( optScale = std::min(0.0122 + std::pow(ply + 2.95, 0.462) * optConstant, 0.213 * limits.time[us] / timeLeft) * optExtra; + maxScale = std::min(6.64, maxConstant + ply / 12.0); } diff --git a/src/timeman.h b/src/timeman.h index 8f1bb56397d..8b763089a70 100644 --- a/src/timeman.h +++ b/src/timeman.h @@ -36,8 +36,12 @@ struct LimitsType; // the maximum available time, the game move number, and other parameters. class TimeManagement { public: - void init( - Search::LimitsType& limits, Color us, int ply, const OptionsMap& options, int& originalPly); + void init(Search::LimitsType& limits, + Color us, + int ply, + const OptionsMap& options, + int& originalPly, + double& originalTimeAdjust); TimePoint optimum() const; TimePoint maximum() const;