Introduce elapsed_time()
authorMarco Costalba <mcostalba@gmail.com>
Thu, 2 Apr 2015 06:52:22 +0000 (08:52 +0200)
committerMarco Costalba <mcostalba@gmail.com>
Fri, 3 Apr 2015 02:19:26 +0000 (04:19 +0200)
And reformat a bit time manager code.

Note that now we set starting search time in think() and
no more in ThreadPool::start_thinking(), the added delay
is less than 1 msec, so below timer resolution (5msec) and
should not affect time lossses ratio.

No functional change.

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

index 7d982c7..ff2e39a 100644 (file)
@@ -41,7 +41,6 @@ namespace Search {
   LimitsType Limits;
   RootMoveVector RootMoves;
   Position RootPos;
-  TimePoint SearchTime;
   StateStackPtr SetupStates;
 }
 
@@ -219,7 +218,7 @@ template uint64_t Search::perft<true>(Position& pos, Depth depth);
 
 void Search::think() {
 
-  TimeMgr.init(Limits, RootPos.side_to_move(), RootPos.game_ply());
+  TimeMgr.init(Limits, RootPos.side_to_move(), RootPos.game_ply(), now());
 
   int contempt = Options["Contempt"] * PawnValueEg / 100; // From centipawns
   DrawValue[ RootPos.side_to_move()] = VALUE_DRAW - Value(contempt);
@@ -402,7 +401,7 @@ namespace {
                 // the UI) before a re-search.
                 if (   multiPV == 1
                     && (bestValue <= alpha || bestValue >= beta)
-                    && now() - SearchTime > 3000)
+                    && TimeMgr.elapsed_time() > 3000)
                     sync_cout << UCI::pv(pos, depth, alpha, beta) << sync_endl;
 
                 // In case of failing low/high increase aspiration window and
@@ -433,9 +432,9 @@ namespace {
 
             if (Signals.stop)
                 sync_cout << "info nodes " << RootPos.nodes_searched()
-                          << " time " << now() - SearchTime << sync_endl;
+                          << " time " << TimeMgr.elapsed_time() << sync_endl;
 
-            else if (PVIdx + 1 == multiPV || now() - SearchTime > 3000)
+            else if (PVIdx + 1 == multiPV || TimeMgr.elapsed_time() > 3000)
                 sync_cout << UCI::pv(pos, depth, alpha, beta) << sync_endl;
         }
 
@@ -462,10 +461,10 @@ namespace {
                 // of the available time has been used or we matched an easyMove
                 // from the previous search and just did a fast verification.
                 if (   RootMoves.size() == 1
-                    || now() - SearchTime > TimeMgr.available_time()
+                    || TimeMgr.elapsed_time() > TimeMgr.available_time()
                     || (   RootMoves[0].pv[0] == easyMove
                         && BestMoveChanges < 0.03
-                        && now() - SearchTime > TimeMgr.available_time() / 10))
+                        && TimeMgr.elapsed_time() > TimeMgr.available_time() / 10))
                 {
                     // If we are allowed to ponder do not stop the search now but
                     // keep pondering until the GUI sends "ponderhit" or "stop".
@@ -485,7 +484,7 @@ namespace {
 
     // Clear any candidate easy move that wasn't stable for the last search
     // iterations; the second condition prevents consecutive fast moves.
-    if (EasyMove.stableCnt < 6 || now() - SearchTime < TimeMgr.available_time())
+    if (EasyMove.stableCnt < 6 || TimeMgr.elapsed_time() < TimeMgr.available_time())
         EasyMove.clear();
 
     // If skill level is enabled, swap best PV line with the sub-optimal one
@@ -833,7 +832,7 @@ moves_loop: // When in check and at SpNode search starts from here
       {
           Signals.firstRootMove = (moveCount == 1);
 
-          if (thisThread == Threads.main() && now() - SearchTime > 3000)
+          if (thisThread == Threads.main() && TimeMgr.elapsed_time() > 3000)
               sync_cout << "info depth " << depth / ONE_PLY
                         << " currmove " << UCI::move(move, pos.is_chess960())
                         << " currmovenumber " << moveCount + PVIdx << sync_endl;
@@ -1482,7 +1481,7 @@ moves_loop: // When in check and at SpNode search starts from here
 string UCI::pv(const Position& pos, Depth depth, Value alpha, Value beta) {
 
   std::stringstream ss;
-  TimePoint elapsed = now() - SearchTime + 1;
+  TimePoint elapsed = TimeMgr.elapsed_time() + 1;
   size_t multiPV = std::min((size_t)Options["MultiPV"], RootMoves.size());
   int selDepth = 0;
 
@@ -1726,7 +1725,7 @@ void Thread::idle_loop() {
 void check_time() {
 
   static TimePoint lastInfoTime = now();
-  TimePoint elapsed = now() - SearchTime;
+  TimePoint elapsed = TimeMgr.elapsed_time();
 
   if (now() - lastInfoTime >= 1000)
   {
index e233c1c..ed2c1e1 100644 (file)
@@ -102,7 +102,6 @@ extern volatile SignalsType Signals;
 extern LimitsType Limits;
 extern RootMoveVector RootMoves;
 extern Position RootPos;
-extern TimePoint SearchTime;
 extern StateStackPtr SetupStates;
 
 void init();
index 048f2a7..2fd3c7a 100644 (file)
@@ -356,8 +356,6 @@ void ThreadPool::start_thinking(const Position& pos, const LimitsType& limits,
                                 StateStackPtr& states) {
   main()->join();
 
-  SearchTime = now(); // As early as possible
-
   Signals.stopOnPonderhit = Signals.firstRootMove = false;
   Signals.stop = Signals.failedLowAtRoot = false;
 
index 04730ab..46ef75f 100644 (file)
@@ -78,15 +78,15 @@ namespace {
 ///  inc >  0 && movestogo == 0 means: x basetime + z increment
 ///  inc >  0 && movestogo != 0 means: x moves in y minutes + z increment
 
-void TimeManager::init(const Search::LimitsType& limits, Color us, int ply)
+void TimeManager::init(const Search::LimitsType& limits, Color us, int ply, TimePoint now)
 {
   int minThinkingTime = Options["Minimum Thinking Time"];
   int moveOverhead    = Options["Move Overhead"];
   int slowMover       = Options["Slow Mover"];
 
-  // Initialize unstablePvFactor to 1 and search times to maximum values
+  start = now;
   unstablePvFactor = 1;
-  optimumSearchTime = maximumSearchTime = std::max(limits.time[us], minThinkingTime);
+  optimumTime = maximumTime = std::max(limits.time[us], minThinkingTime);
 
   const int MaxMTG = limits.movestogo ? std::min(limits.movestogo, MoveHorizon) : MoveHorizon;
 
@@ -105,12 +105,12 @@ void TimeManager::init(const Search::LimitsType& limits, Color us, int ply)
       int t1 = minThinkingTime + remaining<OptimumTime>(hypMyTime, hypMTG, ply, slowMover);
       int t2 = minThinkingTime + remaining<MaxTime    >(hypMyTime, hypMTG, ply, slowMover);
 
-      optimumSearchTime = std::min(t1, optimumSearchTime);
-      maximumSearchTime = std::min(t2, maximumSearchTime);
+      optimumTime = std::min(t1, optimumTime);
+      maximumTime = std::min(t2, maximumTime);
   }
 
   if (Options["Ponder"])
-      optimumSearchTime += optimumSearchTime / 4;
+      optimumTime += optimumTime / 4;
 
-  optimumSearchTime = std::min(optimumSearchTime, maximumSearchTime);
+  optimumTime = std::min(optimumTime, maximumTime);
 }
index 551d738..fe5e0ab 100644 (file)
 #ifndef TIMEMAN_H_INCLUDED
 #define TIMEMAN_H_INCLUDED
 
+#include "misc.h"
+
 /// The TimeManager class computes the optimal time to think depending on the
 /// maximum available time, the game move number and other parameters.
 
 class TimeManager {
 public:
-  void init(const Search::LimitsType& limits, Color us, int ply);
+  void init(const Search::LimitsType& limits, Color us, int ply, TimePoint now);
   void pv_instability(double bestMoveChanges) { unstablePvFactor = 1 + bestMoveChanges; }
-  int available_time() const { return int(optimumSearchTime * unstablePvFactor * 0.76); }
-  int maximum_time() const { return maximumSearchTime; }
+  int available_time() const { return int(optimumTime * unstablePvFactor * 0.76); }
+  int maximum_time() const { return maximumTime; }
+  int elapsed_time() const { return now() - start; }
 
 private:
-  int optimumSearchTime;
-  int maximumSearchTime;
+  TimePoint start;
+  int optimumTime;
+  int maximumTime;
   double unstablePvFactor;
 };