Set timer to a fixed interval
authorMarco Costalba <mcostalba@gmail.com>
Fri, 1 Nov 2013 07:53:29 +0000 (08:53 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Fri, 1 Nov 2013 07:56:15 +0000 (08:56 +0100)
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.

src/search.cpp
src/thread.cpp
src/thread.h

index 7e9b8d77216ae788475f4e7b351297d8b21dcdf8..e2ab9cd933db6bd0774c27a456985f92292db96a 100644 (file)
@@ -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)
index 735cc97caef33aaed97c643ffadab1354d5b678c..a6899de9cbff793b9650ac4b30029c72f4ec20b5 100644 (file)
@@ -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();
   }
 }
index d3dd18679b2a2b9b143caee5cfab79d166094aea..92f5ed33a168b9742c176055759b01cb78c2c6e7 100644 (file)
@@ -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
 };