Multiple lazy stages.
authormstembera <MissingEmail@email>
Sun, 12 Jul 2020 20:58:00 +0000 (13:58 -0700)
committerJoost VandeVondele <Joost.VandeVondele@gmail.com>
Fri, 17 Jul 2020 18:24:02 +0000 (20:24 +0200)
An extension of the lazy eval idea: when the score is sufficiently large
we now skip more granular parts of the eval.

Inspired by an original patch by Moez Jellouli
https://tests.stockfishchess.org/tests/view/5f03b2a159f6f03532894529
Credit to him!

STC https://tests.stockfishchess.org/tests/view/5f0a862c59f6f03532894924
LLR: 2.95 (-2.94,2.94) {-0.50,1.50}
Total: 13504 W: 2684 L: 2472 D: 8348
Ptnml(0-2): 229, 1496, 3111, 1666, 250

LTC https://tests.stockfishchess.org/tests/view/5f0ac0e159f6f0353289495b
LLR: 2.94 (-2.94,2.94) {0.25,1.75}
Total: 31312 W: 3926 L: 3677 D: 23709
Ptnml(0-2): 185, 2773, 9509, 2986, 203

closes https://github.com/official-stockfish/Stockfish/pull/2814

bench: 4541608

src/evaluate.cpp

index ca6ea5c44fd6da373d4e1cf9bf10deca66d2771f..dbb725d4dbf558639b2ce9daf80532d992681e74 100644 (file)
@@ -74,7 +74,8 @@ using namespace Trace;
 namespace {
 
   // Threshold for lazy and space evaluation
-  constexpr Value LazyThreshold  = Value(1400);
+  constexpr Value LazyThreshold1  = Value(1400);
+  constexpr Value LazyThreshold2  = Value(1300);
   constexpr Value SpaceThreshold = Value(12222);
 
   // KingAttackWeights[PieceType] contains king attack weights by piece type
@@ -786,7 +787,7 @@ namespace {
                 && pos.non_pawn_material(BLACK) == RookValueMg
                 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
                 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
-                && (attackedBy[~strongSide][KING] & pos.pieces(~strongSide, PAWN)))
+                && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
             sf = 36;
         else if (pos.count<QUEEN>() == 1)
             sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
@@ -837,9 +838,12 @@ namespace {
     score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
 
     // Early exit if score is high
-    Value v = (mg_value(score) + eg_value(score)) / 2;
-    if (abs(v) > LazyThreshold + pos.non_pawn_material() / 64)
-       return pos.side_to_move() == WHITE ? v : -v;
+    auto lazy_skip = [&](Value lazyThreshold) {
+        return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
+    };
+
+    if (lazy_skip(LazyThreshold1))
+        goto make_v;
 
     // Main evaluation begins here
     initialize<WHITE>();
@@ -856,12 +860,17 @@ namespace {
 
     // More complex interactions that require fully populated attack bitboards
     score +=  king<   WHITE>() - king<   BLACK>()
-            + threats<WHITE>() - threats<BLACK>()
-            + passed< WHITE>() - passed< BLACK>()
+            + passed< WHITE>() - passed< BLACK>();
+
+    if (lazy_skip(LazyThreshold2))
+        goto make_v;
+
+    score +=  threats<WHITE>() - threats<BLACK>()
             + space<  WHITE>() - space<  BLACK>();
 
+make_v:
     // Derive single value from mg and eg parts of score
-    v = winnable(score);
+    Value v = winnable(score);
 
     // In case of tracing add all remaining individual evaluation terms
     if (T)