Skip to content

Commit

Permalink
Time management improvements
Browse files Browse the repository at this point in the history
1. Tune time management parameters.
2. Scale the optimum time and maximum time parameters based on the amount of
   time left, using a logarithmic scale.

Many acknowledgements to @FauziAkram for tuning the parameters and for the
original idea (see
https://tests.stockfishchess.org/tests/view/652f0356de6d262d08d333c5).

STC: https://tests.stockfishchess.org/tests/view/6533938fde6d262d08d39e4d
LLR: 2.94 (-2.94,2.94) <0.00,2.00>
Total: 44320 W: 11301 L: 10982 D: 22037
Ptnml(0-2): 146, 4810, 11920, 5147, 137

LTC: https://tests.stockfishchess.org/tests/view/653477e4de6d262d08d3ae06
LLR: 2.95 (-2.94,2.94) <0.50,2.50>
Total: 146442 W: 37338 L: 36811 D: 72293
Ptnml(0-2): 60, 14975, 42645, 15460, 81

Verification runs:
3+0.03: https://tests.stockfishchess.org/tests/view/65364e7ef127f3553505178a
10+0: https://tests.stockfishchess.org/tests/view/65364e9ff127f3553505178f
180+1.8: https://tests.stockfishchess.org/tests/view/65364ec3f127f35535051794

closes #4843

No functional change.

Co-Authored-By: FauziAkram <[email protected]>
  • Loading branch information
2 people authored and Disservin committed Oct 23, 2023
1 parent a105978 commit cf3dbcb
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 10 deletions.
10 changes: 5 additions & 5 deletions src/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,15 +467,15 @@ void Thread::search() {
// Do we have time for the next iteration? Can we stop searching now?
if (Limits.use_time_management() && !Threads.stop && !mainThread->stopOnPonderhit)
{
double fallingEval = (69 + 13 * (mainThread->bestPreviousAverageScore - bestValue)
double fallingEval = (66 + 14 * (mainThread->bestPreviousAverageScore - bestValue)
+ 6 * (mainThread->iterValue[iterIdx] - bestValue))
/ 619.6;
/ 583.0;
fallingEval = std::clamp(fallingEval, 0.5, 1.5);

// If the bestMove is stable over several iterations, reduce time accordingly
timeReduction = lastBestMoveDepth + 8 < completedDepth ? 1.57 : 0.65;
double reduction = (1.4 + mainThread->previousTimeReduction) / (2.08 * timeReduction);
double bestMoveInstability = 1 + 1.8 * totBestMoveChanges / Threads.size();
timeReduction = lastBestMoveDepth + 8 < completedDepth ? 1.56 : 0.69;
double reduction = (1.4 + mainThread->previousTimeReduction) / (2.03 * timeReduction);
double bestMoveInstability = 1 + 1.79 * totBestMoveChanges / Threads.size();

double totalTime = Time.optimum() * fallingEval * reduction * bestMoveInstability;

Expand Down
14 changes: 9 additions & 5 deletions src/timeman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,11 @@ void TimeManagement::init(Search::LimitsType& limits, Color us, int ply) {
- moveOverhead * (2 + mtg));

// Use extra time with larger increments
double optExtra = std::clamp(1.0 + 12.0 * limits.inc[us] / limits.time[us], 1.0, 1.12);
double optExtra = std::clamp(1.0 + 12.5 * limits.inc[us] / limits.time[us], 1.0, 1.12);

// Calculate time constants based on current time left.
double optConstant = std::min(0.00335 + 0.0003 * std::log10(limits.time[us] / 1000.0), 0.0048);
double maxConstant = std::max(3.6 + 3.0 * std::log10(limits.time[us] / 1000.0), 2.7);

// A user may scale time usage by setting UCI option "Slow Mover"
// Default is 100 and changing this value will probably lose elo.
Expand All @@ -83,10 +87,10 @@ void TimeManagement::init(Search::LimitsType& limits, Color us, int ply) {
// game time for the current move, so also cap to 20% of available game time.
if (limits.movestogo == 0)
{
optScale = std::min(0.0120 + std::pow(ply + 3.0, 0.45) * 0.0039,
optScale = std::min(0.0120 + std::pow(ply + 3.3, 0.44) * optConstant,
0.2 * limits.time[us] / double(timeLeft))
* optExtra;
maxScale = std::min(7.0, 4.0 + ply / 12.0);
maxScale = std::min(6.8, maxConstant + ply / 12.2);
}

// x moves in y seconds (+ z increment)
Expand All @@ -96,10 +100,10 @@ void TimeManagement::init(Search::LimitsType& limits, Color us, int ply) {
maxScale = std::min(6.3, 1.5 + 0.11 * mtg);
}

// Never use more than 80% of the available time for this move
// Limit the maximum possible time for this move
optimumTime = TimePoint(optScale * timeLeft);
maximumTime =
TimePoint(std::min(0.8 * limits.time[us] - moveOverhead, maxScale * optimumTime)) - 10;
TimePoint(std::min(0.84 * limits.time[us] - moveOverhead, maxScale * optimumTime)) - 10;

if (Options["Ponder"])
optimumTime += optimumTime / 4;
Expand Down

0 comments on commit cf3dbcb

Please sign in to comment.