X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=eeca97389fad2bf6b63a2a1436a0c18069f9148d;hp=3309947e1c20f91b1870adde6c8a0e7c5228e504;hb=6008f6538e9c3912c88e89d77ef3e3d3351a6e55;hpb=3df2c01b5769c7ae996fb5b992c06e4a5428ad35 diff --git a/src/search.cpp b/src/search.cpp index 3309947e..eeca9738 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -42,13 +42,11 @@ namespace Search { LimitsType Limits; std::vector RootMoves; Position RootPosition; - Time SearchTime; + Time::point SearchTime; StateStackPtr SetupStates; } using std::string; -using std::cout; -using std::endl; using Eval::evaluate; using namespace Search; @@ -237,8 +235,8 @@ void Search::think() { if (RootMoves.empty()) { - cout << "info depth 0 score " - << score_to_uci(pos.in_check() ? -VALUE_MATE : VALUE_DRAW) << endl; + sync_cout << "info depth 0 score " + << score_to_uci(pos.in_check() ? -VALUE_MATE : VALUE_DRAW) << sync_endl; RootMoves.push_back(MOVE_NONE); goto finalize; @@ -272,7 +270,7 @@ void Search::think() { << " time: " << Limits.time[pos.side_to_move()] << " increment: " << Limits.inc[pos.side_to_move()] << " moves to go: " << Limits.movestogo - << endl; + << std::endl; } Threads.wake_up(); @@ -292,16 +290,16 @@ void Search::think() { if (Options["Use Search Log"]) { - int e = SearchTime.elapsed(); + Time::point elapsed = Time::now() - SearchTime + 1; Log log(Options["Search Log Filename"]); log << "Nodes: " << pos.nodes_searched() - << "\nNodes/second: " << (e > 0 ? pos.nodes_searched() * 1000 / e : 0) + << "\nNodes/second: " << pos.nodes_searched() * 1000 / elapsed << "\nBest move: " << move_to_san(pos, RootMoves[0].pv[0]); StateInfo st; pos.do_move(RootMoves[0].pv[0], st); - log << "\nPonder move: " << move_to_san(pos, RootMoves[0].pv[1]) << endl; + log << "\nPonder move: " << move_to_san(pos, RootMoves[0].pv[1]) << std::endl; pos.undo_move(RootMoves[0].pv[0]); } @@ -314,8 +312,8 @@ finalize: pos.this_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) - << " ponder " << move_to_uci(RootMoves[0].pv[1], Chess960) << endl; + sync_cout << "bestmove " << move_to_uci(RootMoves[0].pv[0], Chess960) + << " ponder " << move_to_uci(RootMoves[0].pv[1], Chess960) << sync_endl; } @@ -367,7 +365,8 @@ namespace { // Start with a small aspiration window and, in case of fail high/low, // research with bigger window until not failing high/low anymore. - do { + while (true) + { // Search starts from ss+1 to allow referencing (ss-1). This is // needed by update gains and ss copy when splitting at Root. bestValue = search(pos, ss+1, alpha, beta, depth * ONE_PLY); @@ -400,8 +399,8 @@ namespace { // Send full PV info to GUI if we are going to leave the loop or // if we have a fail high/low and we are deep in the search. - if ((bestValue > alpha && bestValue < beta) || SearchTime.elapsed() > 2000) - cout << uci_pv(pos, depth, alpha, beta) << endl; + if ((bestValue > alpha && bestValue < beta) || Time::now() - SearchTime > 2000) + sync_cout << uci_pv(pos, depth, alpha, beta) << sync_endl; // In case of failing high/low increase aspiration window and // research, otherwise exit the fail high/low loop. @@ -421,9 +420,15 @@ namespace { else break; - assert(alpha >= -VALUE_INFINITE && beta <= VALUE_INFINITE); + // Search with full window in case we have a win/mate score + if (abs(bestValue) >= VALUE_KNOWN_WIN) + { + alpha = -VALUE_INFINITE; + beta = VALUE_INFINITE; + } - } while (abs(bestValue) < VALUE_KNOWN_WIN); + assert(alpha >= -VALUE_INFINITE && beta <= VALUE_INFINITE); + } } // Skills: Do we need to pick now the best move ? @@ -433,8 +438,8 @@ namespace { if (!Signals.stop && Options["Use Search Log"]) { Log log(Options["Search Log Filename"]); - log << pretty_pv(pos, depth, bestValue, SearchTime.elapsed(), &RootMoves[0].pv[0]) - << endl; + log << pretty_pv(pos, depth, bestValue, Time::now() - SearchTime, &RootMoves[0].pv[0]) + << std::endl; } // Filter out startup noise when monitoring best move stability @@ -453,14 +458,14 @@ namespace { // Stop search if most of available time is already consumed. We // probably don't have enough time to search the first move at the // next iteration anyway. - if (SearchTime.elapsed() > (TimeMgr.available_time() * 62) / 100) + if (Time::now() - SearchTime > (TimeMgr.available_time() * 62) / 100) stop = true; // Stop search early if one move seems to be much better than others if ( depth >= 12 && !stop && ( (bestMoveNeverChanged && pos.captured_piece_type()) - || SearchTime.elapsed() > (TimeMgr.available_time() * 40) / 100)) + || Time::now() - SearchTime > (TimeMgr.available_time() * 40) / 100)) { Value rBeta = bestValue - EasyMoveMargin; (ss+1)->excludedMove = RootMoves[0].pv[0]; @@ -829,10 +834,10 @@ split_point_start: // At split points actual search starts from here { Signals.firstRootMove = (moveCount == 1); - if (thisThread == Threads.main_thread() && SearchTime.elapsed() > 2000) - cout << "info depth " << depth / ONE_PLY - << " currmove " << move_to_uci(move, Chess960) - << " currmovenumber " << moveCount + PVIdx << endl; + if (thisThread == Threads.main_thread() && Time::now() - SearchTime > 2000) + sync_cout << "info depth " << depth / ONE_PLY + << " currmove " << move_to_uci(move, Chess960) + << " currmovenumber " << moveCount + PVIdx << sync_endl; } isPvMove = (PvNode && moveCount <= 1); @@ -1496,7 +1501,7 @@ split_point_start: // At split points actual search starts from here static RKISS rk; // PRNG sequence should be not deterministic - for (int i = Time::current_time().msec() % 50; i > 0; i--) + for (int i = Time::now() % 50; i > 0; i--) rk.rand(); // RootMoves are already sorted by score in descending order @@ -1538,7 +1543,7 @@ split_point_start: // At split points actual search starts from here string uci_pv(const Position& pos, int depth, Value alpha, Value beta) { std::stringstream s; - int t = SearchTime.elapsed(); + Time::point elaspsed = Time::now() - SearchTime + 1; int selDepth = 0; for (size_t i = 0; i < Threads.size(); i++) @@ -1559,12 +1564,12 @@ split_point_start: // At split points actual search starts from here s << "\n"; s << "info depth " << d - << " seldepth " << selDepth - << " score " << (i == PVIdx ? score_to_uci(v, alpha, beta) : score_to_uci(v)) - << " nodes " << pos.nodes_searched() - << " nps " << (t > 0 ? pos.nodes_searched() * 1000 / t : 0) - << " time " << t - << " multipv " << i + 1 + << " seldepth " << selDepth + << " score " << (i == PVIdx ? score_to_uci(v, alpha, beta) : score_to_uci(v)) + << " nodes " << pos.nodes_searched() + << " nps " << pos.nodes_searched() * 1000 / elaspsed + << " time " << elaspsed + << " multipv " << i + 1 << " pv"; for (size_t j = 0; RootMoves[i].pv[j] != MOVE_NONE; j++) @@ -1751,26 +1756,26 @@ void Thread::idle_loop() { void check_time() { - static Time lastInfoTime = Time::current_time(); + static Time::point lastInfoTime = Time::now(); - if (lastInfoTime.elapsed() >= 1000) + if (Time::now() - lastInfoTime >= 1000) { - lastInfoTime.restart(); + lastInfoTime = Time::now(); dbg_print(); } if (Limits.ponder) return; - int e = SearchTime.elapsed(); + Time::point elapsed = Time::now() - SearchTime; bool stillAtFirstMove = Signals.firstRootMove && !Signals.failedLowAtRoot - && e > TimeMgr.available_time(); + && elapsed > TimeMgr.available_time(); - bool noMoreTime = e > TimeMgr.maximum_time() - 2 * TimerResolution + bool noMoreTime = elapsed > TimeMgr.maximum_time() - 2 * TimerResolution || stillAtFirstMove; if ( (Limits.use_time_management() && noMoreTime) - || (Limits.movetime && e >= Limits.movetime)) + || (Limits.movetime && elapsed >= Limits.movetime)) Signals.stop = true; }