From: Joost VandeVondele Date: Tue, 8 May 2018 23:40:32 +0000 (+0200) Subject: Remove goto, limit skipping to NMP X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=4d647428d8f6b02a404e6b7fda5dbbf17090f271 Remove goto, limit skipping to NMP This patch simplifies the control flow in search(), removing an if and a goto. A side effect of the patch is that Stockfish is now a little bit more selective at low depths, because we allow razoring, futility pruning and probcut pruning after a null move. passed STC: LLR: 2.95 (-2.94,2.94) [-3.00,1.00] Total: 32035 W: 6523 L: 6422 D: 19090 http://tests.stockfishchess.org/tests/view/5af142ca0ebc597fb3d39bb6 passed LTC: LLR: 2.95 (-2.94,2.94) [-3.00,1.00] Total: 41431 W: 6187 L: 6097 D: 29147 http://tests.stockfishchess.org/tests/view/5af148770ebc597fb3d39bc1 Ideas for further work: • Use the nodes credit opened by the patch (the increased selectivity) to try somewhat higher razoring, futility or probcut margins at [0..4]. Bench: 4855031 --- diff --git a/src/search.cpp b/src/search.cpp index 744bb788..7875f034 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -682,12 +682,12 @@ namespace { } } - // Step 6. Evaluate the position statically + // Step 6. Static evaluation of the position if (inCheck) { ss->staticEval = eval = VALUE_NONE; improving = false; - goto moves_loop; + goto moves_loop; // Skip early pruning when in check } else if (ttHit) { @@ -710,13 +710,7 @@ namespace { ss->staticEval, TT.generation()); } - improving = ss->staticEval >= (ss-2)->staticEval - ||(ss-2)->staticEval == VALUE_NONE; - - if (ss->excludedMove || !pos.non_pawn_material(pos.side_to_move())) - goto moves_loop; - - // Step 7. Razoring (skipped when in check, ~2 Elo) + // Step 7. Razoring (~2 Elo) if ( !PvNode && depth < 3 * ONE_PLY && eval <= alpha - RazorMargin[depth / ONE_PLY]) @@ -727,7 +721,10 @@ namespace { return v; } - // Step 8. Futility pruning: child node (skipped when in check, ~30 Elo) + improving = ss->staticEval >= (ss-2)->staticEval + || (ss-2)->staticEval == VALUE_NONE; + + // Step 8. Futility pruning: child node (~30 Elo) if ( !rootNode && depth < 7 * ONE_PLY && eval - futility_margin(depth, improving) >= beta @@ -740,6 +737,8 @@ namespace { && (ss-1)->statScore < 30000 && eval >= beta && ss->staticEval >= beta - 36 * depth / ONE_PLY + 225 + && !ss->excludedMove + && pos.non_pawn_material(pos.side_to_move()) && (ss->ply >= thisThread->nmp_ply || ss->ply % 2 != thisThread->nmp_odd)) { assert(eval - beta >= 0); @@ -779,7 +778,7 @@ namespace { } } - // Step 10. ProbCut (skipped when in check, ~10 Elo) + // Step 10. ProbCut (~10 Elo) // If we have a good enough capture and a reduced search returns a value // much above beta, we can (almost) safely prune the previous move. if ( !PvNode @@ -817,7 +816,7 @@ namespace { } } - // Step 11. Internal iterative deepening (skipped when in check, ~2 Elo) + // Step 11. Internal iterative deepening (~2 Elo) if ( depth >= 8 * ONE_PLY && !ttMove) {