From: Marco Costalba Date: Sun, 25 Oct 2015 07:30:07 +0000 (+0100) Subject: Assorted trivia in search.cpp X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=86f04dbcc08e52864c1136d713996e3a0c8d2610 Assorted trivia in search.cpp The only interesting change is the moving of stack[MAX_PLY+4] back to its original position in id_loop (now renamed Thread::search). No functional change. --- diff --git a/src/benchmark.cpp b/src/benchmark.cpp index 8f3e6ae1..70bcafa9 100644 --- a/src/benchmark.cpp +++ b/src/benchmark.cpp @@ -91,8 +91,8 @@ const vector Defaults = { void benchmark(const Position& current, istream& is) { string token; - Search::LimitsType limits; vector fens; + Search::LimitsType limits; // Assign default values to missing arguments string ttSize = (is >> token) ? token : "16"; @@ -103,10 +103,10 @@ void benchmark(const Position& current, istream& is) { Options["Hash"] = ttSize; Options["Threads"] = threads; - Search::reset(); + Search::clear(); if (limitType == "time") - limits.movetime = stoi(limit); // movetime is in ms + limits.movetime = stoi(limit); // movetime is in millisecs else if (limitType == "nodes") limits.nodes = stoi(limit); @@ -151,7 +151,7 @@ void benchmark(const Position& current, istream& is) { cerr << "\nPosition: " << i + 1 << '/' << fens.size() << endl; if (limitType == "perft") - nodes += Search::perft(pos, limits.depth * ONE_PLY); + nodes += Search::perft(pos, limits.depth * ONE_PLY); else { diff --git a/src/endgame.cpp b/src/endgame.cpp index ed6d48db..b64b3d1b 100644 --- a/src/endgame.cpp +++ b/src/endgame.cpp @@ -60,7 +60,7 @@ namespace { const int PushAway [8] = { 0, 5, 20, 40, 60, 80, 90, 100 }; // Pawn Rank based scaling factors used in KRPPKRP endgame - const int KRPPKRPScaleFactors[RANK_NB] = {0, 9, 10, 14, 21, 44, 0, 0}; + const int KRPPKRPScaleFactors[RANK_NB] = { 0, 9, 10, 14, 21, 44, 0, 0 }; #ifndef NDEBUG bool verify_material(const Position& pos, Color c, Value npm, int pawnsCnt) { diff --git a/src/search.cpp b/src/search.cpp index e20eed9f..380c3342 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -174,9 +174,9 @@ void Search::init() { } -/// Search::reset() clears all search memory, to obtain reproducible search results +/// Search::clear() resets to zero search state, to obtain reproducible results -void Search::reset () { +void Search::clear() { TT.clear(); CounterMovesHistory.clear(); @@ -216,7 +216,7 @@ uint64_t Search::perft(Position& pos, Depth depth) { return nodes; } -template uint64_t Search::perft(Position& pos, Depth depth); +template uint64_t Search::perft(Position&, Depth); /// MainThread::think() is called by the main thread when the program receives @@ -344,7 +344,7 @@ void MainThread::think() { void Thread::search(bool isMainThread) { - Stack* ss = stack + 2; // To allow referencing (ss-2) and (ss+2) + Stack stack[MAX_PLY+4], *ss = stack+2; // To allow referencing (ss-2) and (ss+2) Value bestValue, alpha, beta, delta; Move easyMove = MOVE_NONE; @@ -577,7 +577,7 @@ namespace { { // Step 2. Check for aborted search and immediate draw if (Signals.stop.load(std::memory_order_relaxed) || pos.is_draw() || ss->ply >= MAX_PLY) - return ss->ply >= MAX_PLY && !inCheck ? evaluate(pos) + return ss->ply >= MAX_PLY && !inCheck ? evaluate(pos) : DrawValue[pos.side_to_move()]; // Step 3. Mate distance pruning. Even if we mate at the next move our score @@ -836,7 +836,7 @@ moves_loop: // When in check search starts from here if (RootNode && thisThread == Threads.main()) { - Signals.firstRootMove = moveCount == 1; + Signals.firstRootMove = (moveCount == 1); if (Time.elapsed() > 3000) sync_cout << "info depth " << depth / ONE_PLY @@ -1095,7 +1095,7 @@ moves_loop: // When in check search starts from here && is_ok((ss - 1)->currentMove) && is_ok((ss - 2)->currentMove)) { - Value bonus = Value((depth / ONE_PLY) * (depth / ONE_PLY) + depth / ONE_PLY -1); + Value bonus = Value((depth / ONE_PLY) * (depth / ONE_PLY) + depth / ONE_PLY - 1); Square prevPrevSq = to_sq((ss - 2)->currentMove); CounterMovesStats& prevCmh = CounterMovesHistory[pos.piece_on(prevPrevSq)][prevPrevSq]; prevCmh.update(pos.piece_on(prevSq), prevSq, bonus); @@ -1359,8 +1359,8 @@ moves_loop: // When in check search starts from here } - // update_stats() updates killers, history, countermove history and - // countermoves stats for a quiet best move. + // update_stats() updates killers, history, countermove and countermove + // history when a new quiet best move is found. void update_stats(const Position& pos, Stack* ss, Move move, Depth depth, Move* quiets, int quietsCnt) { @@ -1371,7 +1371,7 @@ moves_loop: // When in check search starts from here ss->killers[0] = move; } - Value bonus = Value((depth / ONE_PLY) * (depth / ONE_PLY) + depth / ONE_PLY -1); + Value bonus = Value((depth / ONE_PLY) * (depth / ONE_PLY) + depth / ONE_PLY - 1); Square prevSq = to_sq((ss-1)->currentMove); CounterMovesStats& cmh = CounterMovesHistory[pos.piece_on(prevSq)][prevSq]; @@ -1394,14 +1394,14 @@ moves_loop: // When in check search starts from here cmh.update(pos.moved_piece(quiets[i]), to_sq(quiets[i]), -bonus); } - // Extra penalty for TT move in previous ply when it gets refuted + // Extra penalty for a quiet TT move in previous ply when it gets refuted if ( (ss-1)->moveCount == 1 && !pos.captured_piece_type() && is_ok((ss-2)->currentMove)) { Square prevPrevSq = to_sq((ss-2)->currentMove); CounterMovesStats& prevCmh = CounterMovesHistory[pos.piece_on(prevPrevSq)][prevPrevSq]; - prevCmh.update(pos.piece_on(prevSq), prevSq, -bonus - 2 * ((depth + 1) / ONE_PLY)); + prevCmh.update(pos.piece_on(prevSq), prevSq, -bonus - 2 * (depth + 1) / ONE_PLY); } } @@ -1411,23 +1411,23 @@ moves_loop: // When in check search starts from here Move Skill::pick_best(size_t multiPV) { - // PRNG sequence should be non-deterministic, so we seed it with the time at init const Search::RootMoveVector& rootMoves = Threads.main()->rootMoves; - static PRNG rng(now()); + static PRNG rng(now()); // PRNG sequence should be non-deterministic // RootMoves are already sorted by score in descending order - int variance = std::min(rootMoves[0].score - rootMoves[multiPV - 1].score, PawnValueMg); + Value topScore = rootMoves[0].score; + int delta = std::min(topScore - rootMoves[multiPV - 1].score, PawnValueMg); int weakness = 120 - 2 * level; int maxScore = -VALUE_INFINITE; - // Choose best move. For each move score we add two terms both dependent on + // Choose best move. For each move score we add two terms, both dependent on // weakness. One deterministic and bigger for weaker levels, and one random, // then we choose the move with the resulting highest score. for (size_t i = 0; i < multiPV; ++i) { // This is our magic formula - int push = ( weakness * int(rootMoves[0].score - rootMoves[i].score) - + variance * (rng.rand() % weakness)) / 128; + int push = ( weakness * int(topScore - rootMoves[i].score) + + delta * (rng.rand() % weakness)) / 128; if (rootMoves[i].score + push > maxScore) { @@ -1435,6 +1435,7 @@ moves_loop: // When in check search starts from here best = rootMoves[i].pv[0]; } } + return best; } @@ -1512,7 +1513,8 @@ void RootMove::insert_pv_in_tt(Position& pos) { TTEntry* tte = TT.probe(pos.key(), ttHit); if (!ttHit || tte->move() != m) // Don't overwrite correct entries - tte->save(pos.key(), VALUE_NONE, BOUND_NONE, DEPTH_NONE, m, VALUE_NONE, TT.generation()); + tte->save(pos.key(), VALUE_NONE, BOUND_NONE, DEPTH_NONE, + m, VALUE_NONE, TT.generation()); pos.do_move(m, *st++, pos.gives_check(m, CheckInfo(pos))); } @@ -1522,10 +1524,10 @@ void RootMove::insert_pv_in_tt(Position& pos) { } -/// RootMove::extract_ponder_from_tt() is called in case we have no ponder move before -/// exiting the search, for instance in case we stop the search during a fail high at -/// root. We try hard to have a ponder move to return to the GUI, otherwise in case of -/// 'ponder on' we have nothing to think on. +/// RootMove::extract_ponder_from_tt() is called in case we have no ponder move +/// before exiting the search, for instance in case we stop the search during a +/// fail high at root. We try hard to have a ponder move to return to the GUI, +/// otherwise in case of 'ponder on' we have nothing to think on. bool RootMove::extract_ponder_from_tt(Position& pos) { @@ -1549,11 +1551,11 @@ bool RootMove::extract_ponder_from_tt(Position& pos) } -/// check_time() is called by the timer thread when the timer triggers. It is -/// used to print debug info and, more importantly, to detect when we are out of +/// TimerThread::check_time() is called by when the timer triggers. It is used +/// to print debug info and, more importantly, to detect when we are out of /// available time and thus stop the search. -void check_time() { +void TimerThread::check_time() { static TimePoint lastInfoTime = now(); int elapsed = Time.elapsed(); diff --git a/src/search.h b/src/search.h index 6248cd01..809a15d1 100644 --- a/src/search.h +++ b/src/search.h @@ -103,8 +103,8 @@ extern LimitsType Limits; extern StateStackPtr SetupStates; void init(); -void reset(); -template uint64_t perft(Position& pos, Depth depth); +void clear(); +template uint64_t perft(Position& pos, Depth depth); } // namespace Search diff --git a/src/thread.cpp b/src/thread.cpp index e3194a23..34424d37 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -29,8 +29,6 @@ using namespace Search; ThreadPool Threads; // Global object -extern void check_time(); - namespace { // Helpers to launch a thread after creation and joining before delete. Outside the @@ -83,7 +81,7 @@ void ThreadBase::wait_while(std::atomic& condition) { } -// Thread constructor makes some init but does not launch any execution thread, +// Thread constructor makes some init but does not launch any execution thread, // which will be started only when the constructor returns. Thread::Thread() { @@ -170,7 +168,7 @@ void MainThread::join() { // ThreadPool::init() is called at startup to create and launch requested threads, -// that will go immediately to sleep. We cannot use a constructor because Threads +// that will go immediately to sleep. We cannot use a constructor because Threads // is a static object and we need a fully initialized engine at this point due to // allocation of Endgames in the Thread constructor. diff --git a/src/thread.h b/src/thread.h index 39753f40..c1e55322 100644 --- a/src/thread.h +++ b/src/thread.h @@ -34,10 +34,6 @@ #include "search.h" #include "thread_win32.h" -struct Thread; - -const size_t MAX_THREADS = 128; - /// ThreadBase struct is the base of the hierarchy from where we derive all the /// specialized thread classes. @@ -78,7 +74,6 @@ struct Thread : public ThreadBase { Position rootPos; Search::RootMoveVector rootMoves; Depth rootDepth; - Search::Stack stack[MAX_PLY+4]; HistoryStats history; MovesStats counterMoves; }; @@ -100,6 +95,7 @@ struct TimerThread : public ThreadBase { static const int Resolution = 5; // Millisec between two check_time() calls virtual void idle_loop(); + void check_time(); bool run = false; }; diff --git a/src/uci.cpp b/src/uci.cpp index c5dbafae..044aca3a 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -182,7 +182,7 @@ void UCI::loop(int argc, char* argv[]) { else if (token == "ucinewgame") { - Search::reset(); + Search::clear(); Time.availableNodes = 0; } else if (token == "isready") sync_cout << "readyok" << sync_endl; diff --git a/src/ucioption.cpp b/src/ucioption.cpp index c7f1be8e..f493e840 100644 --- a/src/ucioption.cpp +++ b/src/ucioption.cpp @@ -35,7 +35,7 @@ UCI::OptionsMap Options; // Global object namespace UCI { /// 'On change' actions, triggered by an option's value change -void on_clear_hash(const Option&) { Search::reset(); } +void on_clear_hash(const Option&) { Search::clear(); } void on_hash_size(const Option& o) { TT.resize(o); } void on_logger(const Option& o) { start_logger(o); } void on_threads(const Option&) { Threads.read_uci_options(); } @@ -58,7 +58,7 @@ void init(OptionsMap& o) { o["Write Debug Log"] << Option(false, on_logger); o["Contempt"] << Option(0, -100, 100); - o["Threads"] << Option(1, 1, MAX_THREADS, on_threads); + o["Threads"] << Option(1, 1, 128, on_threads); o["Hash"] << Option(16, 1, MaxHashMB, on_hash_size); o["Clear Hash"] << Option(on_clear_hash); o["Ponder"] << Option(true);