]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Move beta counter variables to the per-thread data
[stockfish] / src / search.cpp
index 64863be166b07f84f53571c10ee79e392f3d210d..ba5ad365af2f1caffb95fa56caa9004ec1520dc5 100644 (file)
@@ -1,7 +1,7 @@
 /*
   Stockfish, a UCI chess playing engine derived from Glaurung 2.1
   Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
-  Copyright (C) 2008 Marco Costalba
+  Copyright (C) 2008-2009 Marco Costalba
 
   Stockfish is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -72,7 +72,8 @@ namespace {
   // Apart for the first one that has its score, following moves
   // normally have score -VALUE_INFINITE, so are ordered according
   // to the number of beta cutoffs occurred under their subtree during
-  // the last iteration.
+  // the last iteration. The counters are per thread variables to avoid
+  // concurrent accessing under SMP case.
 
   struct BetaCounterType {
 
@@ -80,8 +81,6 @@ namespace {
     void clear();
     void add(Color us, Depth d, int threadID);
     void read(Color us, int64_t& our, int64_t& their);
-
-    int64_t hits[THREAD_MAX][2];
   };
 
 
@@ -359,10 +358,11 @@ void SearchStack::initKillers() {
 ////
 
 /// think() is the external interface to Stockfish's search, and is called when
-/// the program receives the UCI 'go' command.  It initializes various
-/// search-related global variables, and calls root_search()
+/// the program receives the UCI 'go' command. It initializes various
+/// search-related global variables, and calls root_search(). It returns false
+/// when a quit command is received during the search.
 
-void think(const Position &pos, bool infinite, bool ponder, int side_to_move,
+bool think(const Position &pos, bool infinite, bool ponder, int side_to_move,
            int time[], int increment[], int movesToGo, int maxDepth,
            int maxNodes, int maxTime, Move searchMoves[]) {
 
@@ -377,7 +377,7 @@ void think(const Position &pos, bool infinite, bool ponder, int side_to_move,
       if (bookMove != MOVE_NONE)
       {
           std::cout << "bestmove " << bookMove << std::endl;
-          return;
+          return true;
       }
   }
 
@@ -541,13 +541,8 @@ void think(const Position &pos, bool infinite, bool ponder, int side_to_move,
   if (UseLogFile)
       LogFile.close();
 
-  if (Quit)
-  {
-      stop_threads();
-      quit_eval();
-      exit(0);
-  }
   Idle = true;
+  return !Quit;
 }
 
 
@@ -894,6 +889,10 @@ namespace {
 
         if (i < MultiPV)
         {
+            // Aspiration window is disabled in multi-pv case
+            if (MultiPV > 1)
+                alpha = -VALUE_INFINITE;
+
             value = -search_pv(pos, ss, -beta, -alpha, newDepth, 1, 0);
             // If the value has dropped a lot compared to the last iteration,
             // set the boolean variable Problem to true. This variable is used
@@ -1894,13 +1893,13 @@ namespace {
   void BetaCounterType::clear() {
 
     for (int i = 0; i < THREAD_MAX; i++)
-        hits[i][WHITE] = hits[i][BLACK] = 0ULL;
+        Threads[i].betaCutOffs[WHITE] = Threads[i].betaCutOffs[BLACK] = 0ULL;
   }
 
   void BetaCounterType::add(Color us, Depth d, int threadID) {
 
     // Weighted count based on depth
-    hits[threadID][us] += int(d);
+    Threads[threadID].betaCutOffs[us] += unsigned(d);
   }
 
   void BetaCounterType::read(Color us, int64_t& our, int64_t& their) {
@@ -1908,8 +1907,8 @@ namespace {
     our = their = 0UL;
     for (int i = 0; i < THREAD_MAX; i++)
     {
-        our += hits[i][us];
-        their += hits[i][opposite_color(us)];
+        our += Threads[i].betaCutOffs[us];
+        their += Threads[i].betaCutOffs[opposite_color(us)];
     }
   }
 
@@ -2332,7 +2331,7 @@ namespace {
       return false;
 
     // Case 4: Don't prune moves with good history.
-    if (!H.ok_to_prune(pos.piece_on(move_from(m)), m, d))
+    if (!H.ok_to_prune(pos.piece_on(mfrom), mto, d))
         return false;
 
     // Case 5: If the moving piece in the threatened move is a slider, don't
@@ -2379,13 +2378,13 @@ namespace {
   void update_history(const Position& pos, Move m, Depth depth,
                       Move movesSearched[], int moveCount) {
 
-    H.success(pos.piece_on(move_from(m)), m, depth);
+    H.success(pos.piece_on(move_from(m)), move_to(m), depth);
 
     for (int i = 0; i < moveCount - 1; i++)
     {
         assert(m != movesSearched[i]);
         if (ok_to_history(pos, movesSearched[i]))
-            H.failure(pos.piece_on(move_from(movesSearched[i])), movesSearched[i]);
+            H.failure(pos.piece_on(move_from(movesSearched[i])), move_to(movesSearched[i]));
     }
   }
 
@@ -2454,6 +2453,7 @@ namespace {
             AbortSearch = true;
             PonderSearch = false;
             Quit = true;
+            return;
         }
         else if(command == "stop")
         {
@@ -2551,19 +2551,21 @@ namespace {
   // after which the bestmove and pondermove will be printed (in id_loop()).
 
   void wait_for_stop_or_ponderhit() {
+
     std::string command;
 
-    while(true) {
-      if(!std::getline(std::cin, command))
-        command = "quit";
+    while (true)
+    {
+        if (!std::getline(std::cin, command))
+            command = "quit";
 
-      if(command == "quit") {
-        stop_threads();
-        quit_eval();
-        exit(0);
-      }
-      else if(command == "ponderhit" || command == "stop")
-        break;
+        if (command == "quit")
+        {
+            Quit = true;
+            break;
+        }
+        else if(command == "ponderhit" || command == "stop")
+            break;
     }
   }