From 8fec8834715a440ac18e24e130888c2c60bab352 Mon Sep 17 00:00:00 2001 From: Stefan Geschwentner Date: Sun, 25 Aug 2019 21:45:58 +0200 Subject: [PATCH] Tweak Late Move Reduction at root Maintain best move counter at the root and allow there only moves which has a counter of zero for Late Move Reduction. For compensation only the first three moves are excluded from Late Move Reduction per default instead the first four moves. What we can further do: - here we use a simple counting scheme but perhaps some aging to fade out early iterations could be helpful - use the best move counter also at inner nodes for LMR and/or pruning STC: LLR: 2.95 (-2.94,2.94) [0.50,4.50] Total: 17414 W: 3984 L: 3733 D: 9697 http://tests.stockfishchess.org/tests/view/5d6234bb0ebc5939d09f2aa2 LTC: LLR: 2.96 (-2.94,2.94) [0.00,3.50] Total: 38058 W: 6448 L: 6166 D: 25444 http://tests.stockfishchess.org/tests/view/5d62681a0ebc5939d09f2f27 Closes https://github.com/official-stockfish/Stockfish/pull/2282 Bench: 3568210 --- src/search.cpp | 6 +++++- src/search.h | 1 + src/thread.cpp | 9 +++++++++ src/thread.h | 1 + 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/search.cpp b/src/search.cpp index f0fa6f05..28cbffd6 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -472,7 +472,10 @@ void Thread::search() { ++failedHighCnt; } else + { + ++rootMoves[pvIdx].bestMoveCount; break; + } delta += delta / 4 + 5; @@ -1072,7 +1075,8 @@ moves_loop: // When in check, search starts from here // Step 16. Reduced depth search (LMR). If the move fails high it will be // re-searched at full depth. if ( depth >= 3 * ONE_PLY - && moveCount > 1 + 3 * rootNode + && moveCount > 1 + 2 * rootNode + && (!rootNode || thisThread->best_move_count(move) == 0) && ( !captureOrPromotion || moveCountPruning || ss->staticEval + PieceValue[EG][pos.captured_piece()] <= alpha diff --git a/src/search.h b/src/search.h index 24c58d30..c77ca3ad 100644 --- a/src/search.h +++ b/src/search.h @@ -70,6 +70,7 @@ struct RootMove { Value previousScore = -VALUE_INFINITE; int selDepth = 0; int tbRank = 0; + int bestMoveCount = 0; Value tbScore; std::vector pv; }; diff --git a/src/thread.cpp b/src/thread.cpp index e5043b6e..5165fd90 100644 --- a/src/thread.cpp +++ b/src/thread.cpp @@ -52,6 +52,15 @@ Thread::~Thread() { stdThread.join(); } +/// Thread::bestMoveCount(Move move) return best move counter for the given root move + +int Thread::best_move_count(Move move) { + + auto rm = std::find(rootMoves.begin() + pvIdx, + rootMoves.begin() + pvLast, move); + + return rm != rootMoves.begin() + pvLast ? rm->bestMoveCount : 0; +} /// Thread::clear() reset histories, usually before a new game diff --git a/src/thread.h b/src/thread.h index c11d1787..ed427b10 100644 --- a/src/thread.h +++ b/src/thread.h @@ -56,6 +56,7 @@ public: void idle_loop(); void start_searching(); void wait_for_search_finished(); + int best_move_count(Move move); Pawns::Table pawnsTable; Material::Table materialTable; -- 2.39.2