X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=58feb77d7038fc49dcb24821dbf9b762fa84925c;hp=66b1d65dedf8c368f9c37a37ff43a178cf26d442;hb=cbcc581a86417ead9f75ae3a9556f97df63b22bf;hpb=87139d018c86211a0636cb1bcedf9572670d9ba6 diff --git a/src/search.cpp b/src/search.cpp index 66b1d65d..58feb77d 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -38,6 +38,7 @@ #include "lock.h" #include "san.h" #include "search.h" +#include "timeman.h" #include "thread.h" #include "tt.h" #include "ucioption.h" @@ -250,8 +251,8 @@ namespace { int MultiPV; // Time managment variables - int SearchStartTime, MaxNodes, MaxDepth, MaxSearchTime; - int AbsoluteMaxSearchTime, ExtraSearchTime, ExactMaxTime; + int SearchStartTime, MaxNodes, MaxDepth, OptimumSearchTime; + int MaximumSearchTime, ExtraSearchTime, ExactMaxTime; bool UseTimeManagement, InfiniteSearch, PonderSearch, StopOnPonderhit; bool FirstRootMove, AbortSearch, Quit, AspirationFailLow; @@ -400,7 +401,7 @@ bool think(const Position& pos, bool infinite, bool ponder, int time[], int incr // Initialize global search variables StopOnPonderhit = AbortSearch = Quit = AspirationFailLow = false; - MaxSearchTime = AbsoluteMaxSearchTime = ExtraSearchTime = 0; + OptimumSearchTime = MaximumSearchTime = ExtraSearchTime = 0; NodesSincePoll = 0; TM.resetNodeCounters(); SearchStartTime = get_system_time(); @@ -473,37 +474,13 @@ bool think(const Position& pos, bool infinite, bool ponder, int time[], int incr int myIncrement = increment[pos.side_to_move()]; if (UseTimeManagement) { - if (!movesToGo) // Sudden death time control - { - if (myIncrement) - { - MaxSearchTime = myTime / 30 + myIncrement; - AbsoluteMaxSearchTime = Max(myTime / 4, myIncrement - 100); - } - else // Blitz game without increment - { - MaxSearchTime = myTime / 30; - AbsoluteMaxSearchTime = myTime / 8; - } - } - else // (x moves) / (y minutes) - { - if (movesToGo == 1) - { - MaxSearchTime = myTime / 2; - AbsoluteMaxSearchTime = (myTime > 3000)? (myTime - 500) : ((myTime * 3) / 4); - } - else - { - MaxSearchTime = myTime / Min(movesToGo, 20); - AbsoluteMaxSearchTime = Min((4 * myTime) / movesToGo, myTime / 3); - } - } + get_search_times(myTime, myIncrement, movesToGo, pos.startpos_ply_counter(), + &OptimumSearchTime, &MaximumSearchTime); if (get_option_value_bool("Ponder")) { - MaxSearchTime += MaxSearchTime / 4; - MaxSearchTime = Min(MaxSearchTime, AbsoluteMaxSearchTime); + OptimumSearchTime += OptimumSearchTime / 4; + OptimumSearchTime = Min(OptimumSearchTime, MaximumSearchTime); } } @@ -649,20 +626,20 @@ namespace { if ( Iteration >= 8 && EasyMove == pv[0] && ( ( rml.get_move_cumulative_nodes(0) > (nodes * 85) / 100 - && current_search_time() > MaxSearchTime / 16) + && current_search_time() > OptimumSearchTime / 16) ||( rml.get_move_cumulative_nodes(0) > (nodes * 98) / 100 - && current_search_time() > MaxSearchTime / 32))) + && current_search_time() > OptimumSearchTime / 32))) stopSearch = true; // Add some extra time if the best move has changed during the last two iterations if (Iteration > 5 && Iteration <= 50) - ExtraSearchTime = BestMoveChangesByIteration[Iteration] * (MaxSearchTime / 2) - + BestMoveChangesByIteration[Iteration-1] * (MaxSearchTime / 3); + ExtraSearchTime = BestMoveChangesByIteration[Iteration] * (OptimumSearchTime / 2) + + BestMoveChangesByIteration[Iteration-1] * (OptimumSearchTime / 3); // Stop search if most of MaxSearchTime is consumed at the end of the // iteration. We probably don't have enough time to search the first // move at the next iteration anyway. - if (current_search_time() > ((MaxSearchTime + ExtraSearchTime) * 80) / 128) + if (current_search_time() > ((OptimumSearchTime + ExtraSearchTime) * 80) / 128) stopSearch = true; if (stopSearch) @@ -1002,7 +979,7 @@ namespace { Move movesSearched[256]; EvalInfo ei; StateInfo st; - const TTEntry* tte; + const TTEntry *tte, *ttx; Key posKey; Move ttMove, move, excludedMove, threatMove; Depth ext, newDepth; @@ -1213,17 +1190,6 @@ namespace { && is_lower_bound(tte->type()) && tte->depth() >= depth - 3 * OnePly; - // Avoid to do an expensive singular extension search on nodes where - // such search had already failed in the past. - if ( !PvNode - && singularExtensionNode - && depth < SingularExtensionDepth[PvNode] + 5 * OnePly) - { - TTEntry* ttx = TT.retrieve(pos.get_exclusion_key()); - if (ttx && is_lower_bound(ttx->type())) - singularExtensionNode = false; - } - // Step 10. Loop through moves // Loop through all legal moves until no moves remain or a beta cutoff occurs while ( bestValue < beta @@ -1249,9 +1215,22 @@ namespace { && move == tte->move() && ext < OnePly) { + // Avoid to do an expensive singular extension search on nodes where + // such search have already been done in the past, so assume the last + // singular extension search result is still valid. + if ( !PvNode + && depth < SingularExtensionDepth[PvNode] + 5 * OnePly + && ((ttx = TT.retrieve(pos.get_exclusion_key())) != NULL)) + { + if (is_upper_bound(ttx->type())) + ext = OnePly; + + singularExtensionNode = false; + } + Value ttValue = value_from_tt(tte->value(), ply); - if (abs(ttValue) < VALUE_KNOWN_WIN) + if (singularExtensionNode && abs(ttValue) < VALUE_KNOWN_WIN) { Value b = ttValue - SingularExtensionMargin; ss->excludedMove = move; @@ -2165,9 +2144,9 @@ namespace { bool stillAtFirstMove = FirstRootMove && !AspirationFailLow - && t > MaxSearchTime + ExtraSearchTime; + && t > OptimumSearchTime + ExtraSearchTime; - bool noMoreTime = t > AbsoluteMaxSearchTime + bool noMoreTime = t > MaximumSearchTime || stillAtFirstMove; if ( (Iteration >= 3 && UseTimeManagement && noMoreTime) @@ -2188,9 +2167,9 @@ namespace { bool stillAtFirstMove = FirstRootMove && !AspirationFailLow - && t > MaxSearchTime + ExtraSearchTime; + && t > OptimumSearchTime + ExtraSearchTime; - bool noMoreTime = t > AbsoluteMaxSearchTime + bool noMoreTime = t > MaximumSearchTime || stillAtFirstMove; if (Iteration >= 3 && UseTimeManagement && (noMoreTime || StopOnPonderhit))