From: Marco Costalba Date: Fri, 1 Nov 2013 07:53:29 +0000 (+0100) Subject: Set timer to a fixed interval X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=a3a0df92a3ed5ce7c98ff596e687d3d6533590c8;ds=sidebyside Set timer to a fixed interval And remove a complex (and broken) formula. Indeed previous code was broken in case of TC with big time increments where available_time() was too similar to total time yielding to many time losses, so for instance: go wtime 2600 winc 2600 info nodes 4432770 time 2601 <-- time forfeit! maximum search time = 2530 ms available_time = 2300 ms For a reference and further details see: https://groups.google.com/forum/?fromgroups=#!topic/fishcooking/dCPAvQDcm2E Speed tested with bench disabling timer alltogheter vs timer set at max resolution, showed we have no speed regressions both in single core and when using all physical cores. No functional change. --- diff --git a/src/search.cpp b/src/search.cpp index 7e9b8d77..e2ab9cd9 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -55,9 +55,6 @@ namespace { // Set to true to force running with one thread. Used for debugging const bool FakeSplit = false; - // This is the minimum interval in msec between two check_time() calls - const int TimerResolution = 5; - // Different node types, used as template parameter enum NodeType { Root, PV, NonPV, SplitPointRoot, SplitPointPV, SplitPointNonPV }; @@ -243,19 +240,12 @@ void Search::think() { Threads[i]->maxPly = 0; Threads.sleepWhileIdle = Options["Idle Threads Sleep"]; - - // Set best timer interval to avoid lagging under time pressure. Timer is - // used to check for remaining available thinking time. - Threads.timer->msec = - Limits.use_time_management() ? std::min(100, std::max(TimeMgr.available_time() / 16, TimerResolution)) : - Limits.nodes ? 2 * TimerResolution - : 100; - + Threads.timer->run = true; Threads.timer->notify_one(); // Wake up the recurring timer id_loop(RootPos); // Let's start searching ! - Threads.timer->msec = 0; // Stop the timer + Threads.timer->run = false; // Stop the timer Threads.sleepWhileIdle = true; // Send idle threads to sleep if (Options["Write Search Log"]) @@ -1764,7 +1754,7 @@ void check_time() { && !Signals.failedLowAtRoot && elapsed > TimeMgr.available_time(); - bool noMoreTime = elapsed > TimeMgr.maximum_time() - 2 * TimerResolution + bool noMoreTime = elapsed > TimeMgr.maximum_time() - 2 * TimerThread::Resolution || stillAtFirstMove; if ( (Limits.use_time_management() && noMoreTime) diff --git a/src/thread.cpp b/src/thread.cpp index 735cc97c..a6899de9 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -101,11 +101,11 @@ void TimerThread::idle_loop() { mutex.lock(); if (!exit) - sleepCondition.wait_for(mutex, msec ? msec : INT_MAX); + sleepCondition.wait_for(mutex, run ? Resolution : INT_MAX); mutex.unlock(); - if (msec) + if (run) check_time(); } } diff --git a/src/thread.h b/src/thread.h index d3dd1867..92f5ed33 100644 --- a/src/thread.h +++ b/src/thread.h @@ -143,9 +143,10 @@ struct MainThread : public Thread { }; struct TimerThread : public ThreadBase { - TimerThread() : msec(0) {} + TimerThread() : run(false) {} virtual void idle_loop(); - int msec; + bool run; + static const int Resolution = 5; // msec between two check_time() calls };