diff options
| author | Scott Gasch <[email protected]> | 2026-10-14 11:16:06 -0700 |
|---|---|---|
| committer | Scott Gasch <[email protected]> | 2026-10-14 11:16:06 -0700 |
| commit | 3845a082df2fd0d1bd059dd4c22c922067be826a (patch) | |
| tree | 01f7059b7d1d7e7f0495a281512a6ac1610a280b /src | |
| parent | 3d54c2cc82366040f00d5901f80dbe4e9d7bfe10 (diff) | |
Remove dead EFP references left over from its removal
EFP (extended futility pruning) was removed from Search()'s move loop
in favor of LMP's joint FH% table, but several comments, a dead
counter (u64EFPPruned, never incremented anywhere), and two unused
defines (EFP_FH_MIN_SAMPLES/EFP_FH_PRUNE_THRESHOLD_PCT_THOUSANDTHS)
were left behind claiming EFP still gates something. Clean these up:
- Delete u64EFPPruned (COUNTERS and g_Options) and its dead
reader/writer in root.c.
- Delete the two unused EFP_FH_* defines in search.c, and the stale
fAnyMoveEFPPruned comment describing a branch that no longer
skips a store.
- Fix dangling prose references to EFP in generate.c, chess.h,
searchsup.c, and testsearch.c that describe present-tense behavior
EFP no longer participates in, preserving the historical rationale
where it's still relevant (e.g. why EstimateHangingMaterialCp can
return a negative value).
Deliberately left alone (flagged for a separate decision, not a
clear delete): script.c's still-live JOINT_EXTRA_VERIFY calibration
labels ("EFP tier1/tier2"), search.c's _PostReduceDepthBucketEfpAligned
(same live mechanism, name only), searchsup.c's LMP_BASE_MOVENUM/
LMP_PER_PLY_MOVENUM dead macros (kept pending a real floor/ceiling
decision), and PLY_INFO.iPositional[2] (now write-only, but removing
it touches Eval()'s call signature everywhere).
Comment/dead-code only, no logic touched.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Diffstat (limited to 'src')
| -rwxr-xr-x | src/chess.h | 15 | ||||
| -rw-r--r-- | src/generate.c | 2 | ||||
| -rw-r--r-- | src/root.c | 6 | ||||
| -rw-r--r-- | src/search.c | 15 | ||||
| -rw-r--r-- | src/searchsup.c | 24 | ||||
| -rw-r--r-- | src/testsearch.c | 4 |
6 files changed, 24 insertions, 42 deletions
diff --git a/src/chess.h b/src/chess.h index 94c9db4..36b90e3 100755 --- a/src/chess.h +++ b/src/chess.h @@ -1268,10 +1268,6 @@ typedef struct _COUNTERS // leftover pool near the leaves. Counts every move this was // applied to. UINT64 u64LMPPruned; - // 2026-10-05: extended futility pruning (EFP, search.c) -- same - // shape as u64LMPPruned above, for the other overt-skip (not - // reduction) mechanism in the move loop. - UINT64 u64EFPPruned; // 2026-10-05: null-move R-factor breakdown -- which whole-ply R // SelectNullmoveRFactor chose, and how often the null-move // search at that R actually failed high. Indexed by R/ONE_PLY, @@ -1709,9 +1705,11 @@ typedef struct _PLY_INFO // -- e.g. a cleaner cross-ply "improving" signal that corrects for // a tier switch (super-lazy vs full) between the two Eval() calls // being compared, instead of just diffing raw iEval values. Not - // yet consumed that way anywhere; currently only the search.c EFP - // gate (VALUE_KNIGHT/VALUE_ROOK margins) reads this, for the - // node-it-was-computed-at only. + // yet consumed that way anywhere; its one reader (search.c's EFP + // gate, VALUE_KNIGHT/VALUE_ROOK margins) was removed along with + // EFP, so this is currently write-only -- flagged, not deleted, + // since removing it means touching Eval()'s piPositional parameter + // at every call site, a bigger change than this cleanup pass. SCORE iPositional[2]; INT iExtensionAmount; FLAG fInCheck; @@ -2077,7 +2075,6 @@ typedef struct _GAME_OPTIONS UINT64 u64JointExtraTries[JOINT_EXTRA_TIER_COUNT]; UINT64 u64JointExtraResearch[JOINT_EXTRA_TIER_COUNT]; UINT64 u64LMPPruned; - UINT64 u64EFPPruned; UINT64 u64NullMoveTriesByR[NULL_R_BUCKETS]; UINT64 u64NullMoveSuccessByR[NULL_R_BUCKETS]; #ifdef PRUNE_VERIFY @@ -2953,7 +2950,7 @@ TestMakeUnmakeMove(void); // Countermove-match tier bonus, placed above GOOD_MOVE (see // generate.c's _ScoreAllMoves quiet-move branch) so a *sufficiently // evidenced* match (see COUNTERMOVE_EVIDENCE_THRESHOLD) escapes -// "leftover" classification -- and the fIsLeftoverMove-gated EFP check -- +// "leftover" classification -- and the fIsLeftoverMove-gated LMP check -- // entirely, becoming its own tier alongside killers. Conservatively // placed below both ply-2 killer slots (FOURTH_KILLER/THIRD_KILLER): // the contested-node A/B harness never found clean evidence a diff --git a/src/generate.c b/src/generate.c index d202384..569face 100644 --- a/src/generate.c +++ b/src/generate.c @@ -4655,7 +4655,7 @@ Routine description: comments for why the promotion is evidence-gated rather than automatic on a bare match. 6. GOOD_MOVE boundary. Below this, "leftover" (see search.c's - fIsLeftoverMove) -- eligible for EFP pruning, but every leftover + fIsLeftoverMove) -- eligible for LMP pruning, but every leftover is still fully ranked via SelectBestWithHistory (movesup.c); the old NumLeftoverMovesToSelect depth-indexed selection budget was retired once evidence showed the leftover pool has real, @@ -469,9 +469,8 @@ Return value: Trace("Null move cutoff rate: %5.3f percent.\n", ((n / d) * 100.0)); #ifdef PERF_COUNTERS - Trace("Overt move skips: LMP=%llu EFP=%llu moves.\n", - ctx->sCounters.tree.u64LMPPruned, - ctx->sCounters.tree.u64EFPPruned); + Trace("Overt move skips: LMP=%llu moves.\n", + ctx->sCounters.tree.u64LMPPruned); { ULONG uR; UINT64 u64TotalTries = 0; @@ -1594,7 +1593,6 @@ Return value: memcpy(g_Options.u64JointExtraResearch, ctx->sCounters.tree.u64JointExtraResearch, sizeof(g_Options.u64JointExtraResearch)); g_Options.u64LMPPruned = ctx->sCounters.tree.u64LMPPruned; - g_Options.u64EFPPruned = ctx->sCounters.tree.u64EFPPruned; memcpy(g_Options.u64NullMoveTriesByR, ctx->sCounters.tree.u64NullMoveTriesByR, sizeof(g_Options.u64NullMoveTriesByR)); memcpy(g_Options.u64NullMoveSuccessByR, ctx->sCounters.tree.u64NullMoveSuccessByR, diff --git a/src/search.c b/src/search.c index 3abb44b..d0d67b9 100644 --- a/src/search.c +++ b/src/search.c @@ -75,15 +75,6 @@ extern FLAG g_fCanSplit[MAX_PLY_PER_SEARCH]; #define PREPARE_TO_TRY_MOVES (2) #define TRY_GENERATED_MOVES (3) -// EFP's fail-high-history exemption: below EFP_FH_MIN_SAMPLES -// observations, GetMoveFailHighPctThousandths's result isn't trusted -// enough to override the static-eval-based decision either way. -// THOUSANDTHS, not whole percent, since 2026-10-02's rename -- 100 -// thousandths == 10%, unchanged in effect from the old whole-percent -// EFP_FH_PRUNE_THRESHOLD of 10. -#define EFP_FH_MIN_SAMPLES (5) -#define EFP_FH_PRUNE_THRESHOLD_PCT_THOUSANDTHS (10000) // 10% - // 2026-10-13: "skip trying null-move at all" on the iEval <= iAlpha // side (alpha-side table, EV-neutral -- the real move loop still runs // and finds the correct score either way; we only forgo the cheap @@ -1848,12 +1839,6 @@ Search(IN SEARCHER_THREAD_CONTEXT *ctx, // --Ed Schroder StoreUpperBound(pos, iBestScore, uDepth, fThreat); } - // else: fail-low (iAlpha == iInitialAlpha) AND fAnyMoveEFPPruned -- - // no sound bound in either direction to store (the skipped move - // could have raised the true value above iBestScore, so it's not a - // valid upper bound; there's no mvBest to offer as a lower bound - // either, since nothing beat alpha). Store nothing rather than - // cache an unsound result. end: ASSERT(IS_VALID_SCORE(iBeta)); diff --git a/src/searchsup.c b/src/searchsup.c index a048d39..d94dbb4 100644 --- a/src/searchsup.c +++ b/src/searchsup.c @@ -281,9 +281,11 @@ Return value: sign in that case rather than clamping it away -- IID's shallow search genuinely knows more than a static material exchange does, and a caller folding this value directly into a margin - calculation (EFP, search.c) WANTS "this move turned out to - actually be good" to look like the opposite of "hung", not like - "hung = 0" -- see search.c's EFP comment. Callers that need a + calculation WANTS "this move turned out to actually be good" to + look like the opposite of "hung", not like "hung = 0" (this + historically mattered for EFP's margin check, search.c, now + removed -- the reasoning is preserved here in case a future + direct-margin consumer reappears). Callers that need a true cp-loss-or-zero reading instead (the "dumb" axis feeding the joint FH table) must go through HangCpBucket, which clamps exactly this case to bucket 0 rather than asserting it away. @@ -795,8 +797,8 @@ Routine description: 2026-10-04: hoisted out of Search()'s move loop (search.c), where this had grown into an inline block setting fPruneReduceEligible plus two more exemption checks (killer-adjacency, countermove - match) immediately below it -- EFP, LMP and LMR all gate on the - combined result. Pulled into one function so the "is this move + match) immediately below it -- EFP (since removed), LMP and LMR all + gated on the combined result. Pulled into one function so the "is this move even a candidate for pruning/reduction" question has a single, named answer instead of three co-located but separately-maintained checks. @@ -860,7 +862,7 @@ Parameters: Return value: FLAG : TRUE iff mv is eligible to be considered for pruning or - reduction (EFP/LMP/LMR still each apply their own further checks + reduction (LMP/LMR still each apply their own further checks on top of this). **/ @@ -1081,7 +1083,7 @@ Routine description: for a move either of those would have exempted. Takes the FH-table lookups (uFHAttempts, uFHPctThousandths, uPredictedFH) as inputs rather than recomputing them -- search.c's move loop already looks - them up once per move for LMP/LMR/EFP to share. + them up once per move for LMP/LMR to share. 2026-10-13: corrected from an earlier version of this comment that claimed four checks including a move-number floor and a depth @@ -1141,8 +1143,8 @@ Return value: FLAG : TRUE iff mv should be pruned outright (skipped, not merely reduced). Live, not audit-only: search.c's move loop actually - `continue`s past mv when this returns TRUE (the same final check - that consumes fThisMoveEFPPruned), after INCrementing + `continue`s past mv when this returns TRUE (the check that + consumes fThisMoveLMPPruned), after INCrementing u64LMPPruned for the script-summary "late-move pruning (overt skip, not reduction)" line under PERF_COUNTERS. @@ -1325,8 +1327,8 @@ ComputeMoveScore(IN SEARCHER_THREAD_CONTEXT *ctx, ASSERT(IS_SAME_MOVE(mv, ctx->sMoveStack.mvf[uMoveNum].mv)); ASSERT(ctx->uPly > 0); - // Every current caller (search.c's EFP check, and - // ComputeMoveExtension's two ComputeMoveScore() call sites) only + // Every current caller (EstimateHangingMaterialCp above, and + // ComputeMoveExtension's own call site below) only // reaches here after MakeMove(ctx, mv) has already succeeded, so // ctx->uPly is always the *child's* ply here -- uMoveNum indexes // the parent's move list, i.e. ctx->uPly - 1, not ctx->uPly. That's diff --git a/src/testsearch.c b/src/testsearch.c index afd2733..8c67819 100644 --- a/src/testsearch.c +++ b/src/testsearch.c @@ -154,7 +154,7 @@ TestSearch(void) // MaintainDynamicMoveOrdering does) still leaves real accumulated // evidence behind. Search is not a pure function of (position, depth) // in the presence of that evidence: a move's own GetMoveFailHighPct -// Thousandths reading (feeding GetLMRReduction/ShouldLatePrune/EFP) +// Thousandths reading (feeding GetLMRReduction/ShouldLatePrune) // depends on it, and it accumulates LIVE during a search as sibling/ // cousin nodes are visited -- so two calls that visit nodes in a // different order (which a warm vs. cold hash table, by design, makes @@ -198,7 +198,7 @@ _FixedDepthSearchScore(SEARCHER_THREAD_CONTEXT *ctx, // *transparent* (changes performance, never the answer) and that this // is checkable by comparing scores across searches that visit // different subsets of the tree -- does not hold in this engine and -// cannot be patched into holding. EFP/LMR pruning decisions depend on +// cannot be patched into holding. LMP/LMR pruning decisions depend on // GLOBAL, LIVE-ACCUMULATING evidence tables (g_HistoryCounters, // g_ContinuationHistory, g_FailHighs) that update as a side effect of // actually VISITING a node, not as a side effect of that node's final |
