From a00a336946fa9e6dcfa39f8b656413d2de032a89 Mon Sep 17 00:00:00 2001 From: Stefan Geschwentner Date: Tue, 12 Nov 2019 18:36:12 +0100 Subject: [PATCH] Prune before extension Switch execution order in search: do move pruning before extension detection. STC: LLR: 2.96 (-2.94,2.94) [-1.50,4.50] Total: 5762 W: 1307 L: 1181 D: 3274 http://tests.stockfishchess.org/tests/view/5dcc56e90ebc59025bcbb833 LTC: LLR: 2.96 (-2.94,2.94) [0.00,3.50] Total: 72956 W: 11959 L: 11585 D: 49412 http://tests.stockfishchess.org/tests/view/5dcc62840ebc59025bcbb96f Closes https://github.com/official-stockfish/Stockfish/pull/2413 Bench: 4532366 --- src/evaluate.cpp | 2 +- src/search.cpp | 80 +++++++++++++++++++++++++----------------------- 2 files changed, 42 insertions(+), 40 deletions(-) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 07bacf8d..dbd2d6d8 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -125,7 +125,7 @@ namespace { constexpr Score PassedRank[RANK_NB] = { S(0, 0), S(10, 28), S(17, 33), S(15, 41), S(62, 72), S(168, 177), S(276, 260) }; - + // OutpostRank[Rank] contains a bonus according to the rank of the outpost constexpr Score OutpostRank[RANK_NB] = { S(0, 0), S(0, 0), S(0, 0), S(28, 18), S(30, 24), S(32, 19) diff --git a/src/search.cpp b/src/search.cpp index b484dcbe..e75db243 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -955,7 +955,45 @@ moves_loop: // When in check, search starts from here movedPiece = pos.moved_piece(move); givesCheck = pos.gives_check(move); - // Step 13. Extensions (~70 Elo) + // Calculate new depth for this move + newDepth = depth - 1; + + // Step 13. Pruning at shallow depth (~170 Elo) + if ( !rootNode + && pos.non_pawn_material(us) + && bestValue > VALUE_MATED_IN_MAX_PLY) + { + // Skip quiet moves if movecount exceeds our FutilityMoveCount threshold + moveCountPruning = moveCount >= futility_move_count(improving, depth); + + if ( !captureOrPromotion + && !givesCheck + && (!PvNode || !pos.advanced_pawn_push(move) || pos.non_pawn_material(~us) > BishopValueMg)) + { + // Reduced depth of the next LMR search + int lmrDepth = std::max(newDepth - reduction(improving, depth, moveCount), 0); + + // Countermoves based pruning (~20 Elo) + if ( lmrDepth < 4 + ((ss-1)->statScore > 0 || (ss-1)->moveCount == 1) + && (*contHist[0])[movedPiece][to_sq(move)] < CounterMovePruneThreshold + && (*contHist[1])[movedPiece][to_sq(move)] < CounterMovePruneThreshold) + continue; + + // Futility pruning: parent node (~2 Elo) + if ( lmrDepth < 6 + && !inCheck + && ss->staticEval + 250 + 211 * lmrDepth <= alpha) + continue; + + // Prune moves with negative SEE (~10 Elo) + if (!pos.see_ge(move, Value(-(31 - std::min(lmrDepth, 18)) * lmrDepth * lmrDepth))) + continue; + } + else if (!pos.see_ge(move, Value(-199) * depth)) // (~20 Elo) + continue; + } + + // Step 14. Extensions (~70 Elo) // Singular extension search (~60 Elo). If all moves but one fail low on a // search of (alpha-s, beta-s), and just one fails high on (alpha, beta), @@ -1009,44 +1047,8 @@ moves_loop: // When in check, search starts from here if (type_of(move) == CASTLING) extension = 1; - // Calculate new depth for this move - newDepth = depth - 1 + extension; - - // Step 14. Pruning at shallow depth (~170 Elo) - if ( !rootNode - && pos.non_pawn_material(us) - && bestValue > VALUE_MATED_IN_MAX_PLY) - { - // Skip quiet moves if movecount exceeds our FutilityMoveCount threshold - moveCountPruning = moveCount >= futility_move_count(improving, depth); - - if ( !captureOrPromotion - && !givesCheck - && (!PvNode || !pos.advanced_pawn_push(move) || pos.non_pawn_material(~us) > BishopValueMg)) - { - // Reduced depth of the next LMR search - int lmrDepth = std::max(newDepth - reduction(improving, depth, moveCount), 0); - - // Countermoves based pruning (~20 Elo) - if ( lmrDepth < 4 + ((ss-1)->statScore > 0 || (ss-1)->moveCount == 1) - && (*contHist[0])[movedPiece][to_sq(move)] < CounterMovePruneThreshold - && (*contHist[1])[movedPiece][to_sq(move)] < CounterMovePruneThreshold) - continue; - - // Futility pruning: parent node (~2 Elo) - if ( lmrDepth < 6 - && !inCheck - && ss->staticEval + 250 + 211 * lmrDepth <= alpha) - continue; - - // Prune moves with negative SEE (~10 Elo) - if (!pos.see_ge(move, Value(-(31 - std::min(lmrDepth, 18)) * lmrDepth * lmrDepth))) - continue; - } - else if ( !(givesCheck && extension) - && !pos.see_ge(move, Value(-199) * depth)) // (~20 Elo) - continue; - } + // Add extension to new depth + newDepth += extension; // Speculative prefetch as early as possible prefetch(TT.first_entry(pos.key_after(move))); -- 2.39.2