From: Marco Costalba Date: Sat, 4 Jun 2016 05:53:29 +0000 (+0200) Subject: Filter root moves filter before copy to threads X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=ca14345ba26fc40e1039029659f57028f510502f Filter root moves filter before copy to threads Currently root moves are copied to all teh threads but are DTZ filtered only in main thread at the beginning of teh search. This patch moves the TB filtering before the copy of root moves fixing issue #679 https://github.com/official-stockfish/Stockfish/issues/679 No bench change. --- diff --git a/src/search.cpp b/src/search.cpp index a26a7bc4..995204f3 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -261,19 +261,6 @@ void MainThread::search() { DrawValue[ us] = VALUE_DRAW - Value(contempt); DrawValue[~us] = VALUE_DRAW + Value(contempt); - TB::Hits = 0; - TB::RootInTB = false; - TB::UseRule50 = Options["Syzygy50MoveRule"]; - TB::ProbeDepth = Options["SyzygyProbeDepth"] * ONE_PLY; - TB::Cardinality = Options["SyzygyProbeLimit"]; - - // Skip TB probing when no TB found: !TBLargest -> !TB::Cardinality - if (TB::Cardinality > TB::MaxCardinality) - { - TB::Cardinality = TB::MaxCardinality; - TB::ProbeDepth = DEPTH_ZERO; - } - if (rootMoves.empty()) { rootMoves.push_back(RootMove(MOVE_NONE)); @@ -283,38 +270,6 @@ void MainThread::search() { } else { - if ( TB::Cardinality >= rootPos.count(WHITE) - + rootPos.count(BLACK) - && !rootPos.can_castle(ANY_CASTLING)) - { - // If the current root position is in the tablebases, then RootMoves - // contains only moves that preserve the draw or the win. - TB::RootInTB = Tablebases::root_probe(rootPos, rootMoves, TB::Score); - - if (TB::RootInTB) - TB::Cardinality = 0; // Do not probe tablebases during the search - - else // If DTZ tables are missing, use WDL tables as a fallback - { - // Filter out moves that do not preserve the draw or the win. - TB::RootInTB = Tablebases::root_probe_wdl(rootPos, rootMoves, TB::Score); - - // Only probe during search if winning - if (TB::Score <= VALUE_DRAW) - TB::Cardinality = 0; - } - - if (TB::RootInTB) - { - TB::Hits = rootMoves.size(); - - if (!TB::UseRule50) - TB::Score = TB::Score > VALUE_DRAW ? VALUE_MATE - MAX_PLY - 1 - : TB::Score < VALUE_DRAW ? -VALUE_MATE + MAX_PLY + 1 - : VALUE_DRAW; - } - } - for (Thread* th : Threads) if (th != this) th->start_searching(); @@ -1661,3 +1616,49 @@ bool RootMove::extract_ponder_from_tt(Position& pos) return false; } + +void Tablebases::filter_root_moves(Position& pos, Search::RootMoves& rootMoves) { + + Hits = 0; + RootInTB = false; + UseRule50 = Options["Syzygy50MoveRule"]; + ProbeDepth = Options["SyzygyProbeDepth"] * ONE_PLY; + Cardinality = Options["SyzygyProbeLimit"]; + + // Skip TB probing when no TB found: !TBLargest -> !TB::Cardinality + if (Cardinality > MaxCardinality) + { + Cardinality = MaxCardinality; + ProbeDepth = DEPTH_ZERO; + } + + if (Cardinality < popcount(pos.pieces()) || pos.can_castle(ANY_CASTLING)) + return; + + // If the current root position is in the tablebases, then RootMoves + // contains only moves that preserve the draw or the win. + RootInTB = root_probe(pos, rootMoves, TB::Score); + + if (RootInTB) + Cardinality = 0; // Do not probe tablebases during the search + + else // If DTZ tables are missing, use WDL tables as a fallback + { + // Filter out moves that do not preserve the draw or the win. + RootInTB = root_probe_wdl(pos, rootMoves, TB::Score); + + // Only probe during search if winning + if (TB::Score <= VALUE_DRAW) + Cardinality = 0; + } + + if (RootInTB) + { + Hits = rootMoves.size(); + + if (!UseRule50) + TB::Score = TB::Score > VALUE_DRAW ? VALUE_MATE - MAX_PLY - 1 + : TB::Score < VALUE_DRAW ? -VALUE_MATE + MAX_PLY + 1 + : VALUE_DRAW; + } +} diff --git a/src/syzygy/tbprobe.h b/src/syzygy/tbprobe.h index 2bcc0834..b23fdf66 100644 --- a/src/syzygy/tbprobe.h +++ b/src/syzygy/tbprobe.h @@ -12,6 +12,7 @@ int probe_wdl(Position& pos, int *success); int probe_dtz(Position& pos, int *success); bool root_probe(Position& pos, Search::RootMoves& rootMoves, Value& score); bool root_probe_wdl(Position& pos, Search::RootMoves& rootMoves, Value& score); +void filter_root_moves(Position& pos, Search::RootMoves& rootMoves); } diff --git a/src/thread.cpp b/src/thread.cpp index 4dc7d9e9..b38bdd6e 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -25,6 +25,7 @@ #include "search.h" #include "thread.h" #include "uci.h" +#include "syzygy/tbprobe.h" ThreadPool Threads; // Global object @@ -169,7 +170,7 @@ int64_t ThreadPool::nodes_searched() { /// ThreadPool::start_thinking() wakes up the main thread sleeping in idle_loop() /// and starts a new search, then returns immediately. -void ThreadPool::start_thinking(const Position& pos, StateListPtr& states, +void ThreadPool::start_thinking(Position& pos, StateListPtr& states, const Search::LimitsType& limits) { main()->wait_for_search_finished(); @@ -183,6 +184,8 @@ void ThreadPool::start_thinking(const Position& pos, StateListPtr& states, || std::count(limits.searchmoves.begin(), limits.searchmoves.end(), m)) rootMoves.push_back(Search::RootMove(m)); + Tablebases::filter_root_moves(pos, rootMoves); + // After ownership transfer 'states' becomes empty, so if we stop the search // and call 'go' again without setting a new position states.get() == NULL. assert(states.get() || setupStates.get()); diff --git a/src/thread.h b/src/thread.h index 0b112de9..4e63fe47 100644 --- a/src/thread.h +++ b/src/thread.h @@ -94,7 +94,7 @@ struct ThreadPool : public std::vector { void exit(); // be initialized and valid during the whole thread lifetime. MainThread* main() { return static_cast(at(0)); } - void start_thinking(const Position&, StateListPtr&, const Search::LimitsType&); + void start_thinking(Position&, StateListPtr&, const Search::LimitsType&); void read_uci_options(); int64_t nodes_searched(); diff --git a/src/uci.cpp b/src/uci.cpp index a9811a9a..4ae66620 100644 --- a/src/uci.cpp +++ b/src/uci.cpp @@ -108,7 +108,7 @@ namespace { // the thinking time and other parameters from the input string, then starts // the search. - void go(const Position& pos, istringstream& is) { + void go(Position& pos, istringstream& is) { Search::LimitsType limits; string token;