X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=a29fd0f64772e9ae7048a52973697f5da99f7fc5;hp=472d53725f1414c89d73161844432308b5a0b94b;hb=ab65d3fd0ecf340842408548bc7f3e6c28ad4c85;hpb=520e680278964931abcaf3e1ab89b24423777999 diff --git a/src/search.cpp b/src/search.cpp index 472d5372..a29fd0f6 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -51,11 +51,6 @@ using std::endl; using Eval::evaluate; using namespace Search; -// For some reason argument-dependent lookup (ADL) doesn't work for Android's -// STLPort, so explicitly qualify following functions. -using std::count; -using std::find; - namespace { // Set to true to force running with one thread. Used for debugging @@ -146,25 +141,6 @@ namespace { Move do_skill_level(); string uci_pv(const Position& pos, int depth, Value alpha, Value beta); - // MovePickerExt class template extends MovePicker and allows to choose at - // compile time the proper moves source according to the type of node. In the - // default case we simply create and use a standard MovePicker object. - template struct MovePickerExt : public MovePicker { - - MovePickerExt(const Position& p, Move ttm, Depth d, const History& h, Stack* ss, Value b) - : MovePicker(p, ttm, d, h, ss, b) {} - }; - - // In case of a SpNode we use split point's shared MovePicker object as moves source - template<> struct MovePickerExt : public MovePicker { - - MovePickerExt(const Position& p, Move ttm, Depth d, const History& h, Stack* ss, Value b) - : MovePicker(p, ttm, d, h, ss, b), mp(ss->sp->mp) {} - - Move next_move() { return mp->next_move(); } - MovePicker* mp; - }; - // is_dangerous() checks whether a move belongs to some classes of known // 'dangerous' moves so that we avoid to prune it. FORCE_INLINE bool is_dangerous(const Position& pos, Move m, bool captureOrPromotion) { @@ -222,24 +198,23 @@ void Search::init() { /// Search::perft() is our utility to verify move generation. All the leaf nodes /// up to the given depth are generated and counted and the sum returned. -int64_t Search::perft(Position& pos, Depth depth) { - - StateInfo st; - int64_t cnt = 0; - - MoveList ml(pos); +size_t Search::perft(Position& pos, Depth depth) { - // At the last ply just return the number of moves (leaf nodes) + // At the last ply just return the number of legal moves (leaf nodes) if (depth == ONE_PLY) - return ml.size(); + return MoveList(pos).size(); + StateInfo st; + size_t cnt = 0; CheckInfo ci(pos); - for ( ; !ml.end(); ++ml) + + for (MoveList ml(pos); !ml.end(); ++ml) { pos.do_move(ml.move(), st, ci, pos.move_gives_check(ml.move(), ci)); cnt += perft(pos, depth - ONE_PLY); pos.undo_move(ml.move()); } + return cnt; } @@ -272,9 +247,9 @@ void Search::think() { { Move bookMove = book.probe(pos, Options["Book File"], Options["Best Book Move"]); - if (bookMove && count(RootMoves.begin(), RootMoves.end(), bookMove)) + if (bookMove && std::count(RootMoves.begin(), RootMoves.end(), bookMove)) { - std::swap(RootMoves[0], *find(RootMoves.begin(), RootMoves.end(), bookMove)); + std::swap(RootMoves[0], *std::find(RootMoves.begin(), RootMoves.end(), bookMove)); goto finalize; } } @@ -515,7 +490,7 @@ namespace { if (skillBest == MOVE_NONE) // Still unassigned ? skillBest = do_skill_level(); - std::swap(RootMoves[0], *find(RootMoves.begin(), RootMoves.end(), skillBest)); + std::swap(RootMoves[0], *std::find(RootMoves.begin(), RootMoves.end(), skillBest)); } } @@ -779,7 +754,7 @@ namespace { MovePicker mp(pos, ttMove, H, pos.captured_piece_type()); CheckInfo ci(pos); - while ((move = mp.next_move()) != MOVE_NONE) + while ((move = mp.next_move()) != MOVE_NONE) if (pos.pl_move_is_legal(move, ci.pinned)) { ss->currentMove = move; @@ -808,7 +783,7 @@ namespace { split_point_start: // At split points actual search starts from here - MovePickerExt mp(pos, ttMove, depth, H, ss, PvNode ? -VALUE_INFINITE : beta); + MovePicker mp(pos, ttMove, depth, H, ss, PvNode ? -VALUE_INFINITE : beta); CheckInfo ci(pos); futilityBase = ss->eval + ss->evalMargin; singularExtensionNode = !RootNode @@ -822,7 +797,7 @@ split_point_start: // At split points actual search starts from here // Step 11. Loop through moves // Loop through all pseudo-legal moves until no moves remain or a beta cutoff occurs while ( bestValue < beta - && (move = mp.next_move()) != MOVE_NONE + && (move = mp.next_move()) != MOVE_NONE && !thisThread->cutoff_occurred() && !Signals.stop) { @@ -834,7 +809,7 @@ split_point_start: // At split points actual search starts from here // At root obey the "searchmoves" option and skip moves not listed in Root // Move List, as a consequence any illegal move is also skipped. In MultiPV // mode we also skip PV moves which have been already searched. - if (RootNode && !count(RootMoves.begin() + PVIdx, RootMoves.end(), move)) + if (RootNode && !std::count(RootMoves.begin() + PVIdx, RootMoves.end(), move)) continue; // At PV and SpNode nodes we want all moves to be legal since the beginning @@ -1010,7 +985,7 @@ split_point_start: // At split points actual search starts from here // be trusted, and we don't update the best move and/or PV. if (RootNode && !Signals.stop) { - RootMove& rm = *find(RootMoves.begin(), RootMoves.end(), move); + RootMove& rm = *std::find(RootMoves.begin(), RootMoves.end(), move); // PV move or new best move ? if (isPvMove || value > alpha) @@ -1213,7 +1188,7 @@ split_point_start: // At split points actual search starts from here // Loop through the moves until no moves remain or a beta cutoff occurs while ( bestValue < beta - && (move = mp.next_move()) != MOVE_NONE) + && (move = mp.next_move()) != MOVE_NONE) { assert(is_ok(move)); @@ -1565,7 +1540,7 @@ split_point_start: // At split points actual search starts from here int t = SearchTime.elapsed(); int selDepth = 0; - for (int i = 0; i < Threads.size(); i++) + for (size_t i = 0; i < Threads.size(); i++) if (Threads[i].maxPly > selDepth) selDepth = Threads[i].maxPly; @@ -1668,11 +1643,15 @@ void RootMove::insert_pv_in_tt(Position& pos) { } -/// Thread::idle_loop() is where the thread is parked when it has no work to do. -/// The parameter 'master_sp', if non-NULL, is a pointer to an active SplitPoint -/// object for which the thread is the master. +/// Thread::idle_loop() is where the thread is parked when it has no work to do -void Thread::idle_loop(SplitPoint* sp_master) { +void Thread::idle_loop() { + + // Pointer 'sp_master', if non-NULL, points to the active SplitPoint + // object for which the thread is the master. + const SplitPoint* sp_master = splitPointsCnt ? curSplitPoint : NULL; + + assert(!sp_master || (sp_master->master == this && is_searching)); // If this thread is the master of a split point and all slaves have // finished their work at this split point, return from the idle loop. @@ -1749,8 +1728,11 @@ void Thread::idle_loop(SplitPoint* sp_master) { // case we are the last slave of the split point. if ( Threads.use_sleeping_threads() && this != sp->master - && !sp->master->is_searching) + && !sp->slavesMask) + { + assert(!sp->master->is_searching); sp->master->wake_up(); + } // After releasing the lock we cannot access anymore any SplitPoint // related data in a safe way becuase it could have been released under