1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-07-11 19:49:14 +00:00

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.
This commit is contained in:
Marco Costalba 2016-06-04 07:53:29 +02:00
parent 7d2a79f037
commit ca14345ba2
5 changed files with 53 additions and 48 deletions

View file

@ -261,19 +261,6 @@ void MainThread::search() {
DrawValue[ us] = VALUE_DRAW - Value(contempt); DrawValue[ us] = VALUE_DRAW - Value(contempt);
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()) if (rootMoves.empty())
{ {
rootMoves.push_back(RootMove(MOVE_NONE)); rootMoves.push_back(RootMove(MOVE_NONE));
@ -283,38 +270,6 @@ void MainThread::search() {
} }
else else
{ {
if ( TB::Cardinality >= rootPos.count<ALL_PIECES>(WHITE)
+ rootPos.count<ALL_PIECES>(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) for (Thread* th : Threads)
if (th != this) if (th != this)
th->start_searching(); th->start_searching();
@ -1661,3 +1616,49 @@ bool RootMove::extract_ponder_from_tt(Position& pos)
return false; 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;
}
}

View file

@ -12,6 +12,7 @@ int probe_wdl(Position& pos, int *success);
int probe_dtz(Position& pos, int *success); int probe_dtz(Position& pos, int *success);
bool root_probe(Position& pos, Search::RootMoves& rootMoves, Value& score); bool root_probe(Position& pos, Search::RootMoves& rootMoves, Value& score);
bool root_probe_wdl(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);
} }

View file

@ -25,6 +25,7 @@
#include "search.h" #include "search.h"
#include "thread.h" #include "thread.h"
#include "uci.h" #include "uci.h"
#include "syzygy/tbprobe.h"
ThreadPool Threads; // Global object 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() /// ThreadPool::start_thinking() wakes up the main thread sleeping in idle_loop()
/// and starts a new search, then returns immediately. /// 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) { const Search::LimitsType& limits) {
main()->wait_for_search_finished(); 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)) || std::count(limits.searchmoves.begin(), limits.searchmoves.end(), m))
rootMoves.push_back(Search::RootMove(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 // After ownership transfer 'states' becomes empty, so if we stop the search
// and call 'go' again without setting a new position states.get() == NULL. // and call 'go' again without setting a new position states.get() == NULL.
assert(states.get() || setupStates.get()); assert(states.get() || setupStates.get());

View file

@ -94,7 +94,7 @@ struct ThreadPool : public std::vector<Thread*> {
void exit(); // be initialized and valid during the whole thread lifetime. void exit(); // be initialized and valid during the whole thread lifetime.
MainThread* main() { return static_cast<MainThread*>(at(0)); } MainThread* main() { return static_cast<MainThread*>(at(0)); }
void start_thinking(const Position&, StateListPtr&, const Search::LimitsType&); void start_thinking(Position&, StateListPtr&, const Search::LimitsType&);
void read_uci_options(); void read_uci_options();
int64_t nodes_searched(); int64_t nodes_searched();

View file

@ -108,7 +108,7 @@ namespace {
// the thinking time and other parameters from the input string, then starts // the thinking time and other parameters from the input string, then starts
// the search. // the search.
void go(const Position& pos, istringstream& is) { void go(Position& pos, istringstream& is) {
Search::LimitsType limits; Search::LimitsType limits;
string token; string token;