X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=53811de04701c4705053dc0d3ed1e52049db0aed;hp=4ba85b4861d38839e80ba78cc2f1d1e76275296c;hb=c1ea5ed6f7204afd6cb03a80ca8d124bd82cc40d;hpb=73be819426a9bf434d4c5fae1f807da565e3697d diff --git a/src/search.cpp b/src/search.cpp index 4ba85b48..53811de0 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -28,7 +28,6 @@ #include #include -#include "bitcount.h" #include "book.h" #include "evaluate.h" #include "history.h" @@ -279,7 +278,7 @@ namespace { Value qsearch(Position& pos, SearchStack ss[], Value alpha, Value beta, Depth depth, int ply, int threadID); void sp_search(SplitPoint* sp, int threadID); void sp_search_pv(SplitPoint* sp, int threadID); - void init_node(const Position& pos, SearchStack ss[], int ply, int threadID); + void init_node(SearchStack ss[], int ply, int threadID); void update_pv(SearchStack ss[], int ply); void sp_update_pv(SearchStack* pss, SearchStack ss[], int ply); bool connected_moves(const Position& pos, Move m1, Move m2); @@ -300,6 +299,7 @@ namespace { void ponderhit(); void print_current_line(SearchStack ss[], int ply, int threadID); void wait_for_stop_or_ponderhit(); + void init_ss_array(SearchStack ss[]); void idle_loop(int threadID, SplitPoint* waitSp); void init_split_point_stack(); @@ -412,7 +412,7 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move, read_weights(pos.side_to_move()); - // Set the number of active threads. + // Set the number of active threads int newActiveThreads = get_option_value_int("Threads"); if (newActiveThreads != ActiveThreads) { @@ -446,7 +446,8 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move, if (movesToGo == 1) { MaxSearchTime = myTime / 2; - AbsoluteMaxSearchTime = Min(myTime / 2, myTime - 500); + AbsoluteMaxSearchTime = + (myTime > 3000)? (myTime - 500) : ((myTime * 3) / 4); } else { MaxSearchTime = myTime / Min(movesToGo, 20); AbsoluteMaxSearchTime = Min((4 * myTime) / movesToGo, myTime / 3); @@ -470,6 +471,10 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move, NodesBetweenPolls = Min(MaxNodes, 30000); InfiniteSearch = true; // HACK } + else if (myTime && myTime < 1000) + NodesBetweenPolls = 1000; + else if (myTime && myTime < 5000) + NodesBetweenPolls = 5000; else NodesBetweenPolls = 30000; @@ -490,9 +495,9 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move, { Value v = id_loop(pos, searchMoves); loseOnTime = ( UseLSNFiltering - && myTime < LSNTime - && myIncrement == 0 - && v < -LSNValue); + && myTime < LSNTime + && myIncrement == 0 + && v < -LSNValue); } else { @@ -637,11 +642,7 @@ namespace { // Initialize TT.new_search(); H.clear(); - for (int i = 0; i < 3; i++) - { - ss[i].init(i); - ss[i].initKillers(); - } + init_ss_array(ss); IterationInfo[1] = IterationInfoType(rml.get_move_score(0), rml.get_move_score(0)); Iteration = 1; @@ -948,7 +949,7 @@ namespace { // Update PV rml.set_move_score(i, value); update_pv(ss, 0); - TT.extract_pv(pos, ss[0].pv); + TT.extract_pv(pos, ss[0].pv, PLY_MAX); rml.set_move_pv(i, ss[0].pv); if (MultiPV == 1) @@ -975,7 +976,10 @@ namespace { std::cout << std::endl; if (UseLogFile) - LogFile << pretty_pv(pos, current_search_time(), Iteration, nodes_searched(), value, ss[0].pv) + LogFile << pretty_pv(pos, current_search_time(), Iteration, nodes_searched(), value, + ((value >= beta)? VALUE_TYPE_LOWER + : ((value <= alpha)? VALUE_TYPE_UPPER : VALUE_TYPE_EXACT)), + ss[0].pv) << std::endl; if (value > alpha) @@ -1032,7 +1036,7 @@ namespace { // Initialize, and make an early exit in case of an aborted search, // an instant draw, maximum ply reached, etc. - init_node(pos, ss, ply, threadID); + init_node(ss, ply, threadID); // After init_node() that calls poll() if (AbortSearch || thread_should_stop(threadID)) @@ -1044,7 +1048,7 @@ namespace { EvalInfo ei; if (ply >= PLY_MAX - 1) - return evaluate(pos, ei, threadID); + return pos.is_check() ? quick_evaluate(pos) : evaluate(pos, ei, threadID); // Mate distance pruning Value oldAlpha = alpha; @@ -1222,7 +1226,7 @@ namespace { // Initialize, and make an early exit in case of an aborted search, // an instant draw, maximum ply reached, etc. - init_node(pos, ss, ply, threadID); + init_node(ss, ply, threadID); // After init_node() that calls poll() if (AbortSearch || thread_should_stop(threadID)) @@ -1234,7 +1238,7 @@ namespace { EvalInfo ei; if (ply >= PLY_MAX - 1) - return evaluate(pos, ei, threadID); + return pos.is_check() ? quick_evaluate(pos) : evaluate(pos, ei, threadID); // Mate distance pruning if (value_mated_in(ply) >= beta) @@ -1334,6 +1338,10 @@ namespace { bool useFutilityPruning = depth < SelectiveDepth && !isCheck; + // Avoid calling evaluate() if we already have the score in TT + if (tte && (tte->type() & VALUE_TYPE_EVAL)) + futilityValue = value_from_tt(tte->value(), ply) + FutilityMargins[int(depth) - 2]; + // Loop through all legal moves until no moves remain or a beta cutoff // occurs. while ( bestValue < beta @@ -1361,7 +1369,8 @@ namespace { { // History pruning. See ok_to_prune() definition if ( moveCount >= 2 + int(depth) - && ok_to_prune(pos, move, ss[ply].threatMove, depth)) + && ok_to_prune(pos, move, ss[ply].threatMove, depth) + && bestValue > value_mated_in(PLY_MAX)) continue; // Value based pruning @@ -1478,7 +1487,7 @@ namespace { // Initialize, and make an early exit in case of an aborted search, // an instant draw, maximum ply reached, etc. - init_node(pos, ss, ply, threadID); + init_node(ss, ply, threadID); // After init_node() that calls poll() if (AbortSearch || thread_should_stop(threadID)) @@ -1521,8 +1530,8 @@ namespace { else staticValue = evaluate(pos, ei, threadID); - if (ply == PLY_MAX - 1) - return evaluate(pos, ei, threadID); + if (ply >= PLY_MAX - 1) + return pos.is_check() ? quick_evaluate(pos) : evaluate(pos, ei, threadID); // Initialize "stand pat score", and return it immediately if it is // at least beta. @@ -1958,6 +1967,7 @@ namespace { // Find a quick score for the move StateInfo st; SearchStack ss[PLY_MAX_PLUS_2]; + init_ss_array(ss); moves[count].move = cur->move; pos.do_move(moves[count].move, st); @@ -2069,7 +2079,7 @@ namespace { // NodesBetweenPolls nodes, init_node() also calls poll(), which polls // for user input and checks whether it is time to stop the search. - void init_node(const Position& pos, SearchStack ss[], int ply, int threadID) { + void init_node(SearchStack ss[], int ply, int threadID) { assert(ply >= 0 && ply < PLY_MAX); assert(threadID >= 0 && threadID < ActiveThreads); @@ -2557,6 +2567,18 @@ namespace { } + // init_ss_array() does a fast reset of the first entries of a SearchStack array + + void init_ss_array(SearchStack ss[]) { + + for (int i = 0; i < 3; i++) + { + ss[i].init(i); + ss[i].initKillers(); + } + } + + // wait_for_stop_or_ponderhit() is called when the maximum depth is reached // while the program is pondering. The point is to work around a wrinkle in // the UCI protocol: When pondering, the engine is not allowed to give a