]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Move moveCount update near the SpNode case
[stockfish] / src / search.cpp
index d022b3de738cd8f982d6edbd172dcc0e219c8392..f3b092d2dc1910365d70245409dbaa2392d6f792 100644 (file)
@@ -280,12 +280,14 @@ namespace {
   Value search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, int ply);
 
   template <NodeType PvNode>
-  inline Value search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, int ply) {
-      return search<PvNode, false>(pos, ss, alpha, beta, depth, ply);
-  }
+  Value qsearch(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, int ply);
 
   template <NodeType PvNode>
-  Value qsearch(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, int ply);
+  inline Value search(Position& pos, SearchStack* ss, Value alpha, Value beta, Depth depth, int ply) {
+
+      return depth < ONE_PLY ? qsearch<PvNode>(pos, ss, alpha, beta, DEPTH_ZERO, ply)
+                             : search<PvNode, false>(pos, ss, alpha, beta, depth, ply);
+  }
 
   template <NodeType PvNode>
   Depth extension(const Position& pos, Move m, bool captureOrPromotion, bool moveIsCheck, bool singleEvasion, bool mateThreat, bool* dangerous);
@@ -999,10 +1001,8 @@ namespace {
     }
 
     // Step 2. Check for aborted search and immediate draw
-    if (AbortSearch || ThreadsMgr.thread_should_stop(threadID))
-        return VALUE_DRAW;
-
-    if (pos.is_draw() || ply >= PLY_MAX - 1)
+    if (   AbortSearch   || ThreadsMgr.thread_should_stop(threadID)
+        || pos.is_draw() || ply >= PLY_MAX - 1)
         return VALUE_DRAW;
 
     // Step 3. Mate distance pruning
@@ -1019,7 +1019,7 @@ namespace {
     posKey = excludedMove ? pos.get_exclusion_key() : pos.get_key();
 
     tte = TT.retrieve(posKey);
-    ttMove = (tte ? tte->move() : MOVE_NONE);
+    ttMove = tte ? tte->move() : MOVE_NONE;
 
     // At PV nodes, we don't use the TT for pruning, but only for move ordering.
     // This is to avoid problems in the following areas:
@@ -1028,12 +1028,9 @@ namespace {
     // * Fifty move rule detection
     // * Searching for a mate
     // * Printing of full PV line
-
     if (!PvNode && tte && ok_to_use_TT(tte, depth, beta, ply))
     {
-        // Refresh tte entry to avoid aging
-        TT.store(posKey, tte->value(), tte->type(), tte->depth(), ttMove, tte->static_value(), tte->static_value_margin());
-
+        TT.refresh(tte);
         ss->bestMove = ttMove; // Can be MOVE_NONE
         return value_from_tt(tte->value(), ply);
     }
@@ -1109,9 +1106,7 @@ namespace {
 
         pos.do_null_move(st);
         (ss+1)->skipNullMove = true;
-
-        nullValue = depth-R*ONE_PLY < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -beta, -alpha, DEPTH_ZERO, ply+1)
-                                              : - search<NonPV>(pos, ss+1, -beta, -alpha, depth-R*ONE_PLY, ply+1);
+        nullValue = -search<NonPV>(pos, ss+1, -beta, -alpha, depth-R*ONE_PLY, ply+1);
         (ss+1)->skipNullMove = false;
         pos.undo_null_move();
 
@@ -1199,16 +1194,17 @@ split_point_start: // At split points actual search starts from here
            && (move = mp.get_next_move()) != MOVE_NONE
            && !ThreadsMgr.thread_should_stop(threadID))
     {
+      assert(move_is_ok(move));
+
       if (SpNode)
       {
           moveCount = ++sp->moveCount;
           lock_release(&(sp->lock));
       }
-
-      assert(move_is_ok(move));
-
-      if (move == excludedMove)
+      else if (move == excludedMove)
           continue;
+      else
+          movesSearched[moveCount++] = move;
 
       moveIsCheck = pos.move_is_check(move, ci);
       captureOrPromotion = pos.move_is_capture_or_promotion(move);
@@ -1240,13 +1236,9 @@ split_point_start: // At split points actual search starts from here
           }
       }
 
-      newDepth = depth - ONE_PLY + ext;
-
       // Update current move (this must be done after singular extension search)
-      movesSearched[moveCount] = ss->currentMove = move;
-
-      if (!SpNode)
-          moveCount++;
+      ss->currentMove = move;
+      newDepth = depth - ONE_PLY + ext;
 
       // Step 12. Futility pruning (is omitted in PV nodes)
       if (   !PvNode
@@ -1295,8 +1287,7 @@ split_point_start: // At split points actual search starts from here
       // Step extra. pv search (only in PV nodes)
       // The first move in list is the expected PV
       if (!SpNode && PvNode && moveCount == 1)
-          value = newDepth < ONE_PLY ? -qsearch<PV>(pos, ss+1, -beta, -alpha, DEPTH_ZERO, ply+1)
-                                     : - search<PV>(pos, ss+1, -beta, -alpha, newDepth, ply+1);
+          value = -search<PV>(pos, ss+1, -beta, -alpha, newDepth, ply+1);
       else
       {
           // Step 14. Reduced depth search
@@ -1314,8 +1305,7 @@ split_point_start: // At split points actual search starts from here
               {
                   alpha = SpNode ? sp->alpha : alpha;
                   Depth d = newDepth - ss->reduction;
-                  value = d < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -(alpha+1), -alpha, DEPTH_ZERO, ply+1)
-                                      : - search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, ply+1);
+                  value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, ply+1);
 
                   doFullDepthSearch = (value > alpha);
               }
@@ -1339,15 +1329,13 @@ split_point_start: // At split points actual search starts from here
           if (doFullDepthSearch)
           {
               alpha = SpNode ? sp->alpha : alpha;
-              value = newDepth < ONE_PLY ? -qsearch<NonPV>(pos, ss+1, -(alpha+1), -alpha, DEPTH_ZERO, ply+1)
-                                         : - search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth, ply+1);
+              value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, newDepth, ply+1);
 
               // Step extra. pv search (only in PV nodes)
               // Search only for possible new PV nodes, if instead value >= beta then
               // parent node fails low with value <= alpha and tries another move.
               if (PvNode && value > alpha && value < beta)
-                  value = newDepth < ONE_PLY ? -qsearch<PV>(pos, ss+1, -beta, -alpha, DEPTH_ZERO, ply+1)
-                                             : - search<PV>(pos, ss+1, -beta, -alpha, newDepth, ply+1);
+                  value = -search<PV>(pos, ss+1, -beta, -alpha, newDepth, ply+1);
           }
       }
 
@@ -1408,7 +1396,7 @@ split_point_start: // At split points actual search starts from here
 
     if (SpNode)
     {
-        /* Here we have the lock still grabbed */
+        // Here we have the lock still grabbed
         sp->slaves[threadID] = 0;
         lock_release(&(sp->lock));
         return bestValue;
@@ -2212,9 +2200,6 @@ split_point_start: // At split points actual search starts from here
 
     assert(threadID >= 0 && threadID < MAX_THREADS);
 
-    int i;
-    bool allFinished = false;
-
     while (true)
     {
         // Slave threads can exit as soon as AllThreadsShouldExit raises,
@@ -2230,23 +2215,23 @@ split_point_start: // At split points actual search starts from here
         // instead of wasting CPU time polling for work.
         while (   threadID >= ActiveThreads
                || threads[threadID].state == THREAD_INITIALIZING
-               || threads[threadID].state == THREAD_AVAILABLE)
+               || (!sp && threads[threadID].state == THREAD_AVAILABLE))
         {
-            lock_grab(&MPLock);
+            assert(!sp);
+            assert(threadID != 0);
+
+            if (AllThreadsShouldExit)
+                break;
 
-            // Test with lock held to avoid races with wake_sleeping_thread()
-            for (i = 0; sp && i < ActiveThreads && !sp->slaves[i]; i++) {}
-            allFinished = (i == ActiveThreads);
+            lock_grab(&MPLock);
 
-            // Retest sleep conditions under lock protection
-            if (   AllThreadsShouldExit
-                || allFinished
-                || !(   threadID >= ActiveThreads
-                     || threads[threadID].state == THREAD_INITIALIZING
-                     || threads[threadID].state == THREAD_AVAILABLE))
+            // Retest condition under lock protection
+            if (!(   threadID >= ActiveThreads
+                  || threads[threadID].state == THREAD_INITIALIZING
+                  || (!sp && threads[threadID].state == THREAD_AVAILABLE)))
             {
                 lock_release(&MPLock);
-                break;
+                continue;
             }
 
             // Put thread to sleep
@@ -2276,19 +2261,14 @@ split_point_start: // At split points actual search starts from here
             assert(threads[threadID].state == THREAD_SEARCHING);
 
             threads[threadID].state = THREAD_AVAILABLE;
-
-            // Wake up master thread so to allow it to return from the idle loop in
-            // case we are the last slave of the split point.
-            if (threadID != tsp->master && threads[tsp->master].state == THREAD_AVAILABLE)
-                wake_sleeping_thread(tsp->master);
         }
 
         // If this thread is the master of a split point and all slaves have
         // finished their work at this split point, return from the idle loop.
-        for (i = 0; sp && i < ActiveThreads && !sp->slaves[i]; i++) {}
-        allFinished = (i == ActiveThreads);
+        int i = 0;
+        for ( ; sp && i < ActiveThreads && !sp->slaves[i]; i++) {}
 
-        if (allFinished)
+        if (i == ActiveThreads)
         {
             // Because sp->slaves[] is reset under lock protection,
             // be sure sp->lock has been released before to return.
@@ -2344,6 +2324,7 @@ split_point_start: // At split points actual search starts from here
 #if !defined(_MSC_VER)
         pthread_t pthread[1];
         ok = (pthread_create(pthread, NULL, init_thread, (void*)(&i)) == 0);
+        pthread_detach(pthread[0]);
 #else
         ok = (CreateThread(NULL, 0, init_thread, (LPVOID)(&i), 0, NULL) != NULL);
 #endif
@@ -2495,7 +2476,6 @@ split_point_start: // At split points actual search starts from here
 
     // Initialize the split point object
     splitPoint.parent = masterThread.splitPoint;
-    splitPoint.master = master;
     splitPoint.stopRequest = false;
     splitPoint.ply = ply;
     splitPoint.depth = depth;