Skip to content

Commit 114ddb7

Browse files
vondelesnicolet
authored andcommitted
Update Elo estimates for terms in search
This updates estimates from 1.5 year ago, and adds missing terms. All estimates from tests run on fishtest at 10+0.1 (STC), 20000 games, error bars +- 3 Elo, see the original message in the pull request for the full list of tests. Noteworthy changes are step 7 (futility pruning) going from ~30 to ~50 Elo and step 13 (pruning at shallow depth) going from ~170 to ~200 Elo. Full list of tests: #2401 @Rocky640 made the suggestion to look at time control dependence of these terms. I picked two large terms (early futility pruning and singular extension), so with small relative error. It turns out it is actually quite interesting (see figure 1). Contrary to my expectation, the Elo gain for early futility pruning is pretty time control sensitive, while singular extension gain is not. Figure 1: TC dependence of two search terms ![elo_search_tc]( http://cassio.free.fr/divers/elo_search_tc.png ) Going back to the old measurement of futility pruning (30 Elo vs today 50 Elo), the code is actually identical but the margins have changed. It seems like a nice example of how connected terms in search really are, i.e. the value of early futility pruning increased significantly due to changes elsewhere in search. No functional change.
1 parent 7f62320 commit 114ddb7

File tree

1 file changed

+16
-16
lines changed

1 file changed

+16
-16
lines changed

src/search.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,7 @@ namespace {
808808
tte->save(posKey, VALUE_NONE, ttPv, BOUND_NONE, DEPTH_NONE, MOVE_NONE, eval);
809809
}
810810

811-
// Step 7. Razoring (~2 Elo)
811+
// Step 7. Razoring (~1 Elo)
812812
if ( !rootNode // The required rootNode PV handling is not available in qsearch
813813
&& depth < 2
814814
&& eval <= alpha - RazorMargin)
@@ -817,7 +817,7 @@ namespace {
817817
improving = (ss-2)->staticEval == VALUE_NONE ? (ss->staticEval >= (ss-4)->staticEval
818818
|| (ss-4)->staticEval == VALUE_NONE) : ss->staticEval >= (ss-2)->staticEval;
819819

820-
// Step 8. Futility pruning: child node (~30 Elo)
820+
// Step 8. Futility pruning: child node (~50 Elo)
821821
if ( !PvNode
822822
&& depth < 6
823823
&& eval - futility_margin(depth, improving) >= beta
@@ -917,7 +917,7 @@ namespace {
917917
}
918918
}
919919

920-
// Step 11. Internal iterative deepening (~2 Elo)
920+
// Step 11. Internal iterative deepening (~1 Elo)
921921
if (depth >= 7 && !ttMove)
922922
{
923923
search<NT>(pos, ss, alpha, beta, depth - 7, cutNode);
@@ -982,7 +982,7 @@ namespace {
982982
// Calculate new depth for this move
983983
newDepth = depth - 1;
984984

985-
// Step 13. Pruning at shallow depth (~170 Elo)
985+
// Step 13. Pruning at shallow depth (~200 Elo)
986986
if ( !rootNode
987987
&& pos.non_pawn_material(us)
988988
&& bestValue > VALUE_MATED_IN_MAX_PLY)
@@ -1002,7 +1002,7 @@ namespace {
10021002
&& (*contHist[1])[movedPiece][to_sq(move)] < CounterMovePruneThreshold)
10031003
continue;
10041004

1005-
// Futility pruning: parent node (~2 Elo)
1005+
// Futility pruning: parent node (~5 Elo)
10061006
if ( lmrDepth < 6
10071007
&& !inCheck
10081008
&& ss->staticEval + 255 + 182 * lmrDepth <= alpha
@@ -1012,17 +1012,17 @@ namespace {
10121012
+ (*contHist[3])[movedPiece][to_sq(move)] < 30000)
10131013
continue;
10141014

1015-
// Prune moves with negative SEE (~10 Elo)
1015+
// Prune moves with negative SEE (~20 Elo)
10161016
if (!pos.see_ge(move, Value(-(32 - std::min(lmrDepth, 18)) * lmrDepth * lmrDepth)))
10171017
continue;
10181018
}
1019-
else if (!pos.see_ge(move, Value(-194) * depth)) // (~20 Elo)
1019+
else if (!pos.see_ge(move, Value(-194) * depth)) // (~25 Elo)
10201020
continue;
10211021
}
10221022

1023-
// Step 14. Extensions (~70 Elo)
1023+
// Step 14. Extensions (~75 Elo)
10241024

1025-
// Singular extension search (~60 Elo). If all moves but one fail low on a
1025+
// Singular extension search (~70 Elo). If all moves but one fail low on a
10261026
// search of (alpha-s, beta-s), and just one fails high on (alpha, beta),
10271027
// then that move is singular and should be extended. To verify this we do
10281028
// a reduced search on all the other moves but the ttMove and if the
@@ -1101,7 +1101,7 @@ namespace {
11011101
// Step 15. Make the move
11021102
pos.do_move(move, st, givesCheck);
11031103

1104-
// Step 16. Reduced depth search (LMR). If the move fails high it will be
1104+
// Step 16. Reduced depth search (LMR, ~200 Elo). If the move fails high it will be
11051105
// re-searched at full depth.
11061106
if ( depth >= 3
11071107
&& moveCount > 1 + 2 * rootNode
@@ -1122,31 +1122,31 @@ namespace {
11221122
if (th.marked())
11231123
r++;
11241124

1125-
// Decrease reduction if position is or has been on the PV
1125+
// Decrease reduction if position is or has been on the PV (~10 Elo)
11261126
if (ttPv)
11271127
r -= 2;
11281128

1129-
// Decrease reduction if opponent's move count is high (~10 Elo)
1129+
// Decrease reduction if opponent's move count is high (~5 Elo)
11301130
if ((ss-1)->moveCount > 14)
11311131
r--;
11321132

1133-
// Decrease reduction if ttMove has been singularly extended
1133+
// Decrease reduction if ttMove has been singularly extended (~3 Elo)
11341134
if (singularLMR)
11351135
r -= 2;
11361136

11371137
if (!captureOrPromotion)
11381138
{
1139-
// Increase reduction if ttMove is a capture (~0 Elo)
1139+
// Increase reduction if ttMove is a capture (~5 Elo)
11401140
if (ttCapture)
11411141
r++;
11421142

1143-
// Increase reduction for cut nodes (~5 Elo)
1143+
// Increase reduction for cut nodes (~10 Elo)
11441144
if (cutNode)
11451145
r += 2;
11461146

11471147
// Decrease reduction for moves that escape a capture. Filter out
11481148
// castling moves, because they are coded as "king captures rook" and
1149-
// hence break make_move(). (~5 Elo)
1149+
// hence break make_move(). (~2 Elo)
11501150
else if ( type_of(move) == NORMAL
11511151
&& !pos.see_ge(reverse_move(move)))
11521152
r -= 2;

0 commit comments

Comments
 (0)