]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Micro-optimize castleRights update
[stockfish] / src / search.cpp
index 572a8ac8b2e0b1fda34c6d1867d7069d9653a1ae..73050bdf12534065495807d016753debd2e8ca3b 100644 (file)
@@ -307,11 +307,7 @@ void Search::think() {
           << endl;
   }
 
-  for (int i = 0; i < Threads.size(); i++)
-  {
-      Threads[i].maxPly = 0;
-      Threads[i].wake_up();
-  }
+  Threads.set_size(Options["Threads"]);
 
   // Set best timer interval to avoid lagging under time pressure. Timer is
   // used to check for remaining available thinking time.
@@ -348,7 +344,7 @@ finalize:
   // but if we are pondering or in infinite search, we shouldn't print the best
   // move before we are told to do so.
   if (!Signals.stop && (Limits.ponder || Limits.infinite))
-      Threads.wait_for_stop_or_ponderhit();
+      Threads[pos.thread()].wait_for_stop_or_ponderhit();
 
   // Best move could be MOVE_NONE when searching on a stalemate position
   cout << "bestmove " << move_to_uci(RootMoves[0].pv[0], Chess960)
@@ -1061,7 +1057,9 @@ split_point_start: // At split points actual search starts from here
               sp->bestValue = value;
               sp->ss->bestMove = move;
               sp->alpha = alpha;
-              sp->is_betaCutoff = (value >= beta);
+
+              if (value >= beta)
+                  sp->cutoff = true;
           }
       }
 
@@ -1769,14 +1767,14 @@ void RootMove::extract_pv_from_tt(Position& pos) {
   pos.do_move(m, *st++);
 
   while (   (tte = TT.probe(pos.key())) != NULL
-         && tte->move() != MOVE_NONE
-         && pos.is_pseudo_legal(tte->move())
-         && pos.pl_move_is_legal(tte->move(), pos.pinned_pieces())
+         && (m = tte->move()) != MOVE_NONE // Local copy, TT entry could change
+         && pos.is_pseudo_legal(m)
+         && pos.pl_move_is_legal(m, pos.pinned_pieces())
          && ply < MAX_PLY
          && (!pos.is_draw<false>() || ply < 2))
   {
-      pv.push_back(tte->move());
-      pos.do_move(tte->move(), *st++);
+      pv.push_back(m);
+      pos.do_move(m, *st++);
       ply++;
   }
   pv.push_back(MOVE_NONE);
@@ -1864,10 +1862,16 @@ void Thread::idle_loop(SplitPoint* sp_master) {
       {
           assert(!do_sleep && !do_exit);
 
-          // Copy split point position and search stack and call search()
+          lock_grab(Threads.splitLock);
+
+          assert(is_searching);
+          SplitPoint* sp = curSplitPoint;
+
+          lock_release(Threads.splitLock);
+
           Stack ss[MAX_PLY_PLUS_2];
-          SplitPoint* sp = splitPoint;
           Position pos(*sp->pos, threadID);
+          int master = sp->master;
 
           memcpy(ss, sp->ss - 1, 4 * sizeof(Stack));
           (ss+1)->sp = sp;
@@ -1885,21 +1889,26 @@ void Thread::idle_loop(SplitPoint* sp_master) {
 
           assert(is_searching);
 
-          // We return from search with lock held
+          is_searching = false;
           sp->slavesMask &= ~(1ULL << threadID);
           sp->nodes += pos.nodes_searched();
-          lock_release(sp->lock);
 
-          is_searching = false;
+          // After releasing the lock we cannot access anymore any SplitPoint
+          // related data in a reliably way becuase it could have been released
+          // under our feet by the sp master.
+          lock_release(sp->lock);
 
           // 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 (   Threads.use_sleeping_threads()
-              && threadID != sp->master
-              && !Threads[sp->master].is_searching)
-              Threads[sp->master].wake_up();
+              && threadID != master
+              && !Threads[master].is_searching)
+              Threads[master].wake_up();
       }
   }
+  // In helpful master concept a master can help only a sub-tree of its split
+  // point, and because here is all finished is not possible master is booked.
+  assert(!is_searching);
 }