From 7b278aab9f61620b9dba31896b38aeea1eb911e2 Mon Sep 17 00:00:00 2001 From: Joost VandeVondele Date: Sun, 7 Nov 2021 11:01:03 +0100 Subject: [PATCH] Reduce use of lazyEval In case the evaluation at root is large, discourage the use of lazyEval. This fixes https://github.com/official-stockfish/Stockfish/issues/3772 or at least improves it significantly. In this case, poor play with large odds can be observed, in extreme cases leading to a loss despite large advantage: r1bq1b1r/ppp3p1/3p1nkp/n3p3/2B1P2N/2NPB3/PPP2PPP/R3K2R b KQ - 5 9 With this patch the poor move is only considered up to depth 13, in master up to depth 28. The patch did not pass at LTC with Elo gainer bounds, but with slightly positive Elo nevertheless (95% LOS). STC: LLR: 2.94 (-2.94,2.94) <0.00,2.50> Total: 40368 W: 10318 L: 10041 D: 20009 Ptnml(0-2): 103, 4493, 10725, 4750, 113 https://tests.stockfishchess.org/tests/view/61800ad259e71df00dcc420d LTC: LLR: -2.94 (-2.94,2.94) <0.50,3.00> Total: 212288 W: 52997 L: 52692 D: 106599 Ptnml(0-2): 112, 22038, 61549, 22323, 122 https://tests.stockfishchess.org/tests/view/618050d959e71df00dcc426d closes https://github.com/official-stockfish/Stockfish/pull/3780 Bench: 7127040 --- src/evaluate.cpp | 5 ++++- src/search.cpp | 2 +- src/thread.h | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 2f1d5067..a503b0c8 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -988,7 +988,9 @@ namespace { // Early exit if score is high auto lazy_skip = [&](Value lazyThreshold) { - return abs(mg_value(score) + eg_value(score)) > lazyThreshold + pos.non_pawn_material() / 32; + return abs(mg_value(score) + eg_value(score)) > lazyThreshold + + std::abs(pos.this_thread()->bestValue) * 5 / 4 + + pos.non_pawn_material() / 32; }; if (lazy_skip(LazyThreshold1)) @@ -1126,6 +1128,7 @@ std::string Eval::trace(Position& pos) { std::memset(scores, 0, sizeof(scores)); pos.this_thread()->trend = SCORE_ZERO; // Reset any dynamic contempt + pos.this_thread()->bestValue = VALUE_ZERO; // Reset bestValue for lazyEval v = Evaluation(pos).value(); diff --git a/src/search.cpp b/src/search.cpp index 090a7931..11d1df32 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -286,7 +286,7 @@ void Thread::search() { // The latter is needed for statScore and killer initialization. Stack stack[MAX_PLY+10], *ss = stack+7; Move pv[MAX_PLY+1]; - Value bestValue, alpha, beta, delta; + Value alpha, beta, delta; Move lastBestMove = MOVE_NONE; Depth lastBestMoveDepth = 0; MainThread* mainThread = (this == Threads.main() ? Threads.main() : nullptr); diff --git a/src/thread.h b/src/thread.h index fae866c4..38793739 100644 --- a/src/thread.h +++ b/src/thread.h @@ -64,6 +64,7 @@ public: uint64_t nodesLastExplosive; uint64_t nodesLastNormal; std::atomic nodes, tbHits, bestMoveChanges; + Value bestValue; int selDepth, nmpMinPly; Color nmpColor; ExplosionState state; -- 2.39.2