summaryrefslogtreecommitdiff
path: root/src/chess.h
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2026-10-13 23:22:10 -0700
committerScott Gasch <[email protected]>2026-10-13 23:22:10 -0700
commitdad4620a92f51a1d0825fc99fa98fd2b16c0f280 (patch)
tree865a0f210b6d3ad49779617ba73a3e04c02aad4e /src/chess.h
parent7400001fc2d43a507b54281f9860c60177860fe5 (diff)
Add alpha-side static null-move skip gate and Search() perf hoists
Reuses the joint FH% table on the iEval <= iAlpha side to skip the null-move probe attempt when it's predicted unlikely to succeed (EV-neutral: the real move loop still runs regardless). Also hoists several node-constant computations (ImproveBucket, MP split-eligibility checks) out of the per-move loop in Search(), and adds GNUmakefile overrides for sweeping NULLMOVE_SKIP_FH_CEILING_THOUSANDTHS and SKIP_SELECT_AFTER_N_MOVES from the command line. Self-play vs. head is trending positive overnight (1020 games, llr=+1.36, score=0.527) but not yet conclusive -- committing now to checkpoint the change while the match continues. Co-Authored-By: Claude Sonnet 5 <[email protected]>
Diffstat (limited to 'src/chess.h')
-rwxr-xr-xsrc/chess.h16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/chess.h b/src/chess.h
index 91c6a0c..94c9db4 100755
--- a/src/chess.h
+++ b/src/chess.h
@@ -1353,9 +1353,22 @@ typedef struct _COUNTERS
// 2026-10-10: static (score-only, no verification search)
// null-move cutoff, gated on iEval > iBeta and the beta-side
// FH% table (g_uBetaFHThousandths) predicting a cutoff with
- // >95% confidence -- see search.c's fTryBetaPruningHere block.
+ // >95% confidence -- see search.c's static-NM block.
UINT64 u64QuickNullMoves;
UINT64 u64QuickNullMoveSuccess;
+
+ // 2026-10-13: opposite-direction (iEval <= iAlpha) check --
+ // reuses the alpha/leftover-move table (g_uJointFHThousandths)
+ // as a proxy for "would a free tempo even reach beta here," to
+ // decide whether trying the real null-move probe is worth its
+ // own cost. EV-neutral: the real move loop always still runs
+ // and finds the correct score regardless -- this only skips
+ // the probe attempt on the (hopefully rare) occasion it would
+ // have succeeded. No companion "success" counter for the same
+ // reason u64NullMoveSkippedLowFH never had one before: skipping
+ // is never wrong in the score sense, only in the opportunity-
+ // cost sense, which isn't separately observable here.
+ UINT64 u64NullMoveSkippedLowFH;
#ifdef TEST_NULL
// Precision/recall calibration for the null-move try/avoid
// decision. Indexed by _NullCalibBucketIndex() (search.c).
@@ -1687,6 +1700,7 @@ typedef struct _PLY_INFO
SCORE iBeta;
#endif
SCORE iEval;
+
// 2026-09-17: per-color iPositional from the SAME Eval() call that
// set iEval above -- previously discarded (Search() called Eval()
// with piPositional==NULL). Stored per-ply, right next to iEval,