Tweak Late Move Reduction at root
authorStefan Geschwentner <Stefan-Geschwentner@web.de>
Sun, 25 Aug 2019 19:45:58 +0000 (21:45 +0200)
committerSt├ęphane Nicolet <stephanenicoletsuriphone@gmail.com>
Mon, 26 Aug 2019 06:49:55 +0000 (08:49 +0200)
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
src/search.h
src/thread.cpp
src/thread.h

index f0fa6f05132522d5ca043e3a56e51841ab2c16a2..28cbffd6d4caa67d66d0210acdcfe7ce7dd5a978 100644 (file)
@@ -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
index 24c58d3085e2fee1143dc6465c4fa1272ddeeccc..c77ca3ad8991dfea8568f2e70d054fe4c9b8ac96 100644 (file)
@@ -70,6 +70,7 @@ struct RootMove {
   Value previousScore = -VALUE_INFINITE;
   int selDepth = 0;
   int tbRank = 0;
+  int bestMoveCount = 0;
   Value tbScore;
   std::vector<Move> pv;
 };
index e5043b6ea355ba4dce1c2e52f038a76d9275257f..5165fd90ae949e17ade2e2d8453f552e16fc053c 100644 (file)
@@ -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
 
index c11d17873df5621ed4892ddbce016332ef55e24c..ed427b10c1edbf0a384c6e558f4525318683154c 100644 (file)
@@ -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;