From: lucasart Date: Mon, 18 Jan 2016 22:20:16 +0000 (+0000) Subject: Retire RootNode template X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=28933a580eeb4b9a2d717f06c789a6c13dfef19c;hp=12eb345ebd9d93114ce26b8bdc6095245e8149c4 Retire RootNode template There is no reason to compile 3 different copies of search(). PV nodes are on the cold path, and PvNode is a template parameter, so there is no cost in computing: const bool RootNode = PvNode && (ss-1)->ply == 0; And this simplifies code a tiny bit as well. Speed impact is negligible on my machine (i7-3770k, linux 4.2, gcc 5.2): nps +/- test 2378605 3118 master 2383128 2793 diff -4523 2746 Bench: 7751425 No functional change. Resolves #568 --- diff --git a/src/search.cpp b/src/search.cpp index a4bf172a..0ccf3266 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -62,7 +62,7 @@ using namespace Search; namespace { // Different node types, used as a template parameter - enum NodeType { Root, PV, NonPV }; + enum NodeType { NonPV, PV }; // Razoring and futility margin based on depth const int razor_margin[4] = { 483, 570, 603, 554 }; @@ -441,7 +441,7 @@ void Thread::search() { // high/low anymore. while (true) { - bestValue = ::search(rootPos, ss, alpha, beta, rootDepth, false); + bestValue = ::search(rootPos, ss, alpha, beta, rootDepth, false); // Bring the best move to the front. It is critical that sorting // is done with a stable algorithm because all the values but the @@ -589,8 +589,8 @@ namespace { template Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, bool cutNode) { - const bool RootNode = NT == Root; - const bool PvNode = NT == PV || NT == Root; + const bool PvNode = NT == PV; + const bool rootNode = PvNode && (ss-1)->ply == 0; assert(-VALUE_INFINITE <= alpha && alpha < beta && beta <= VALUE_INFINITE); assert(PvNode || (alpha == beta - 1)); @@ -632,7 +632,7 @@ namespace { if (PvNode && thisThread->maxPly < ss->ply) thisThread->maxPly = ss->ply; - if (!RootNode) + if (!rootNode) { // Step 2. Check for aborted search and immediate draw if (Signals.stop.load(std::memory_order_relaxed) || pos.is_draw() || ss->ply >= MAX_PLY) @@ -664,7 +664,7 @@ namespace { posKey = excludedMove ? pos.exclusion_key() : pos.key(); tte = TT.probe(posKey, ttHit); ttValue = ttHit ? value_from_tt(tte->value(), ss->ply) : VALUE_NONE; - ttMove = RootNode ? thisThread->rootMoves[thisThread->PVIdx].pv[0] + ttMove = rootNode ? thisThread->rootMoves[thisThread->PVIdx].pv[0] : ttHit ? tte->move() : MOVE_NONE; // At non-PV nodes we check for an early TT cutoff @@ -685,7 +685,7 @@ namespace { } // Step 4a. Tablebase probe - if (!RootNode && TB::Cardinality) + if (!rootNode && TB::Cardinality) { int piecesCnt = pos.count(WHITE) + pos.count(BLACK); @@ -762,7 +762,7 @@ namespace { } // Step 7. Futility pruning: child node (skipped when in check) - if ( !RootNode + if ( !rootNode && depth < 7 * ONE_PLY && eval - futility_margin(depth) >= beta && eval < VALUE_KNOWN_WIN // Do not return unproven wins @@ -846,7 +846,7 @@ namespace { { Depth d = depth - 2 * ONE_PLY - (PvNode ? DEPTH_ZERO : depth / 4); ss->skipEarlyPruning = true; - search(pos, ss, alpha, beta, d, true); + search(pos, ss, alpha, beta, d, true); ss->skipEarlyPruning = false; tte = TT.probe(posKey, ttHit); @@ -866,7 +866,7 @@ moves_loop: // When in check search starts from here || ss->staticEval == VALUE_NONE ||(ss-2)->staticEval == VALUE_NONE; - singularExtensionNode = !RootNode + singularExtensionNode = !rootNode && depth >= 8 * ONE_PLY && ttMove != MOVE_NONE /* && ttValue != VALUE_NONE Already implicit in the next condition */ @@ -887,13 +887,13 @@ moves_loop: // When in check 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 && !std::count(thisThread->rootMoves.begin() + thisThread->PVIdx, + if (rootNode && !std::count(thisThread->rootMoves.begin() + thisThread->PVIdx, thisThread->rootMoves.end(), move)) continue; ss->moveCount = ++moveCount; - if (RootNode && thisThread == Threads.main() && Time.elapsed() > 3000) + if (rootNode && thisThread == Threads.main() && Time.elapsed() > 3000) sync_cout << "info depth " << depth / ONE_PLY << " currmove " << UCI::move(move, pos.is_chess960()) << " currmovenumber " << moveCount + thisThread->PVIdx << sync_endl; @@ -937,7 +937,7 @@ moves_loop: // When in check search starts from here newDepth = depth - ONE_PLY + extension; // Step 13. Pruning at shallow depth - if ( !RootNode + if ( !rootNode && !captureOrPromotion && !inCheck && !givesCheck @@ -979,7 +979,7 @@ moves_loop: // When in check search starts from here prefetch(TT.first_entry(pos.key_after(move))); // Check for legality just before making the move - if (!RootNode && !pos.legal(move, ci.pinned)) + if (!rootNode && !pos.legal(move, ci.pinned)) { ss->moveCount = --moveCount; continue; @@ -1038,7 +1038,7 @@ moves_loop: // When in check search starts from here // For PV nodes only, do a full PV search on the first move or after a fail // high (in the latter case search only if value < beta), otherwise let the // parent node fail low with value <= alpha and try another move. - if (PvNode && (moveCount == 1 || (value > alpha && (RootNode || value < beta)))) + if (PvNode && (moveCount == 1 || (value > alpha && (rootNode || value < beta)))) { (ss+1)->pv = pv; (ss+1)->pv[0] = MOVE_NONE; @@ -1061,7 +1061,7 @@ moves_loop: // When in check search starts from here if (Signals.stop.load(std::memory_order_relaxed)) return VALUE_ZERO; - if (RootNode) + if (rootNode) { RootMove& rm = *std::find(thisThread->rootMoves.begin(), thisThread->rootMoves.end(), move); @@ -1105,7 +1105,7 @@ moves_loop: // When in check search starts from here bestMove = move; - if (PvNode && !RootNode) // Update pv even in fail-high case + if (PvNode && !rootNode) // Update pv even in fail-high case update_pv(ss->pv, move, (ss+1)->pv); if (PvNode && value < beta) // Update alpha! Always alpha < beta @@ -1176,7 +1176,6 @@ moves_loop: // When in check search starts from here const bool PvNode = NT == PV; - assert(NT == PV || NT == NonPV); assert(InCheck == !!pos.checkers()); assert(alpha >= -VALUE_INFINITE && alpha < beta && beta <= VALUE_INFINITE); assert(PvNode || (alpha == beta - 1));