]> git.sesse.net Git - stockfish/blobdiff - src/search.cpp
Thread::splitPoint is a volatile pointer
[stockfish] / src / search.cpp
index a349fd6c7687c33002fbad2b5f6821a4785650b3..ba0a4f0c596386b623f52ee8b15ddcf9bbaef22b 100644 (file)
@@ -188,7 +188,7 @@ namespace {
   const Depth IIDDepth[2] = { 8 * OnePly /* non-PV */, 5 * OnePly /* PV */};
 
   // At Non-PV nodes we do an internal iterative deepening search
-  // when the static evaluation is at most IIDMargin below beta.
+  // when the static evaluation is bigger then beta - IIDMargin.
   const Value IIDMargin = Value(0x100);
 
   // Step 11. Decide the new search depth
@@ -234,9 +234,6 @@ namespace {
   // better than the second best move.
   const Value EasyMoveMargin = Value(0x200);
 
-  // Maximum number of moves to try before to split (strong YBWC)
-  const int MaximumSplitMove = 3;
-
   // Last seconds noise filtering (LSN)
   const bool UseLSNFiltering = true;
   const int LSNTime = 4000; // In milliseconds
@@ -1098,7 +1095,7 @@ namespace {
     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);
+        TT.store(posKey, tte->value(), tte->type(), tte->depth(), ttMove, tte->static_value(), tte->king_danger());
 
         ss[ply].currentMove = ttMove; // Can be MOVE_NONE
         return value_from_tt(tte->value(), ply);
@@ -1109,8 +1106,11 @@ namespace {
     isCheck = pos.is_check();
     if (!isCheck)
     {
-        if (tte && (tte->type() & VALUE_TYPE_EVAL))
-            ss[ply].eval = value_from_tt(tte->value(), ply);
+        if (tte && tte->static_value() != VALUE_NONE)
+        {
+            ss[ply].eval = tte->static_value();
+            ei.kingDanger[pos.side_to_move()] = tte->king_danger();
+        }
         else
             ss[ply].eval = evaluate(pos, ei, threadID);
 
@@ -1207,8 +1207,8 @@ namespace {
     }
 
     // Step 9. Internal iterative deepening
-    if (   depth >= IIDDepth[PvNode]
-        && ttMove == MOVE_NONE
+    if (    depth >= IIDDepth[PvNode]
+        && (ttMove == MOVE_NONE || (PvNode && tte->depth() <= depth - 4 * OnePly))
         && (PvNode || (!isCheck && ss[ply].eval >= beta - IIDMargin)))
     {
         Depth d = (PvNode ? depth - 2 * OnePly : depth / 2);
@@ -1309,8 +1309,8 @@ namespace {
           value = -search<PV>(pos, ss, -beta, -alpha, newDepth, ply+1, false, threadID);
       else
       {
-          // Step 14. Reduced search
-          // if the move fails high will be re-searched at full depth.
+          // Step 14. Reduced depth search
+          // If the move fails high will be re-searched at full depth.
           bool doFullDepthSearch = true;
 
           if (    depth >= 3 * OnePly
@@ -1325,6 +1325,16 @@ namespace {
                   value = -search<NonPV>(pos, ss, -(alpha+1), -alpha, newDepth-ss[ply].reduction, ply+1, true, threadID);
                   doFullDepthSearch = (value > alpha);
               }
+
+              // The move failed high, but if reduction is very big we could
+              // face a false positive, retry with a less aggressive reduction,
+              // if the move fails high again then go with full depth search.
+              if (doFullDepthSearch && ss[ply].reduction > 2 * OnePly)
+              {
+                  ss[ply].reduction = OnePly;
+                  value = -search<NonPV>(pos, ss, -(alpha+1), -alpha, newDepth-ss[ply].reduction, ply+1, true, threadID);
+                  doFullDepthSearch = (value > alpha);
+              }
           }
 
           // Step 15. Full depth search
@@ -1366,7 +1376,6 @@ namespace {
       if (   TM.active_threads() > 1
           && bestValue < beta
           && depth >= MinimumSplitDepth
-          && (PvNode || moveCount > MaximumSplitMove * MinimumSplitDepth / depth)
           && Iteration <= 99
           && TM.available_thread_exists(threadID)
           && !AbortSearch
@@ -1389,13 +1398,13 @@ namespace {
         return bestValue;
 
     if (bestValue <= oldAlpha)
-        TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_UPPER, depth, MOVE_NONE);
+        TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_UPPER, depth, MOVE_NONE, ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
 
     else if (bestValue >= beta)
     {
         TM.incrementBetaCounter(pos.side_to_move(), depth, threadID);
         move = ss[ply].pv[ply];
-        TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, depth, move);
+        TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, depth, move, ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
         if (!pos.move_is_capture_or_promotion(move))
         {
             update_history(pos, move, depth, movesSearched, moveCount);
@@ -1403,7 +1412,7 @@ namespace {
         }
     }
     else
-        TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_EXACT, depth, ss[ply].pv[ply]);
+        TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_EXACT, depth, ss[ply].pv[ply], ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
 
     assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
 
@@ -1453,8 +1462,6 @@ namespace {
 
     if (!PvNode && tte && ok_to_use_TT(tte, depth, beta, ply))
     {
-        assert(tte->type() != VALUE_TYPE_EVAL);
-
         ss[ply].currentMove = ttMove; // Can be MOVE_NONE
         return value_from_tt(tte->value(), ply);
     }
@@ -1464,8 +1471,11 @@ namespace {
     // Evaluate the position statically
     if (isCheck)
         staticValue = -VALUE_INFINITE;
-    else if (tte && (tte->type() & VALUE_TYPE_EVAL))
-        staticValue = value_from_tt(tte->value(), ply);
+    else if (tte && tte->static_value() != VALUE_NONE)
+    {
+        staticValue = tte->static_value();
+        ei.kingDanger[pos.side_to_move()] = tte->king_danger();
+    }
     else
         staticValue = evaluate(pos, ei, threadID);
 
@@ -1482,8 +1492,8 @@ namespace {
     if (bestValue >= beta)
     {
         // Store the score to avoid a future costly evaluation() call
-        if (!isCheck && !tte && ei.kingDanger[pos.side_to_move()] == 0)
-            TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_EV_LO, Depth(-127*OnePly), MOVE_NONE);
+        if (!isCheck && !tte)
+            TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, Depth(-127*OnePly), MOVE_NONE, ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
 
         return bestValue;
     }
@@ -1581,20 +1591,19 @@ namespace {
     {
         // If bestValue isn't changed it means it is still the static evaluation
         // of the node, so keep this info to avoid a future evaluation() call.
-        ValueType type = (bestValue == staticValue && !ei.kingDanger[pos.side_to_move()] ? VALUE_TYPE_EV_UP : VALUE_TYPE_UPPER);
-        TT.store(pos.get_key(), value_to_tt(bestValue, ply), type, d, MOVE_NONE);
+        TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_UPPER, d, MOVE_NONE, ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
     }
     else if (bestValue >= beta)
     {
         move = ss[ply].pv[ply];
-        TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, d, move);
+        TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, d, move, ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
 
         // Update killers only for good checking moves
         if (!pos.move_is_capture_or_promotion(move))
             update_killers(move, ss[ply]);
     }
     else
-        TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_EXACT, d, ss[ply].pv[ply]);
+        TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_EXACT, d, ss[ply].pv[ply], ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
 
     assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
 
@@ -1688,7 +1697,7 @@ namespace {
       pos.do_move(move, st, ci, moveIsCheck);
 
       // Step 14. Reduced search
-      // if the move fails high will be re-searched at full depth.
+      // If the move fails high will be re-searched at full depth.
       bool doFullDepthSearch = true;
 
       if (   !dangerous
@@ -1703,6 +1712,17 @@ namespace {
               value = -search<NonPV>(pos, ss, -(localAlpha+1), -localAlpha, newDepth-ss[sp->ply].reduction, sp->ply+1, true, threadID);
               doFullDepthSearch = (value > localAlpha);
           }
+
+          // The move failed high, but if reduction is very big we could
+          // face a false positive, retry with a less aggressive reduction,
+          // if the move fails high again then go with full depth search.
+          if (doFullDepthSearch && ss[sp->ply].reduction > 2 * OnePly)
+          {
+              ss[sp->ply].reduction = OnePly;
+              Value localAlpha = sp->alpha;
+              value = -search<NonPV>(pos, ss, -(localAlpha+1), -localAlpha, newDepth-ss[sp->ply].reduction, sp->ply+1, true, threadID);
+              doFullDepthSearch = (value > localAlpha);
+          }
       }
 
       // Step 15. Full depth search