summaryrefslogtreecommitdiff
path: root/src/root.c
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2026-09-05 21:52:40 -0700
committerScott Gasch <[email protected]>2026-09-05 21:52:40 -0700
commit9e995e7c39a83ae9b5ba86f3346e0281744bf773 (patch)
tree27b4587287b0259fba2811084aba1f60c9e1e6bb /src/root.c
parent53694883d63674a97a3960514dd4e0a4e1b67f01 (diff)
King-safety recalibration, lazy-eval material floor, eval hot-path trimming
Recalibrate iKingSwingP90 against the bitboard-rewritten CountKingSafetyDefects (~1.28B samples via new CALIBRATE_POSITIONAL/ CALIBRATE_BASE_MARGIN/CALIBRATE_MARGIN_SAFETY diagnostic build flags, board_representation/EVAL.md section 9). Add LAZY_EVAL_MIN_MATERIAL: measured the regular lazy exit's real swing exceeding its own assumed margin 20.6% of the time in near-bare-king endgames (vs <=0.36% elsewhere) -- skip lazy eval entirely below that material floor. Double the stale search.c/searchsup.c CountKingSafetyDefects extension thresholds as a stopgap pending their own recalibration. Eval hot-path trimming (measured via EVAL_TIME, ~1759 -> ~1386 avg cycles/eval on a representative middlegame position): - Pull _GetFileStormDefects out of EstimatePositionalScore's hot path (cost more than the "cheap cached lookup" it was assumed to be, running on ~90% of all Eval() calls). - Add pos->bbOccupiedSide[2], incrementally maintained alongside bbOccupied, so _BuildFriendlySideBB is a field read instead of a 6-term OR. - Switch CoorFromBitBoardRank8ToRank1/Rank1ToRank8 to the existing static-inline FastFirstBit/FastLastBit (same bsf/bsr instruction, no call/ret overhead). - Defer EvalPasserRaces' uRacerDist/fDontCountMeOut past its no-passer early return. - Remove the mailbox-era "max mobility in a row" term from _EvalBishop/_EvalRook (no bitboard-mobility equivalent need for it). - Simplify _EvalBishopPairs and rook file-openness/passer bonuses to flat DNA-tunable constants instead of distance/pawn-count-scaled tables, rook file-openness now a branchless bitboard-indexed lookup. - Remove pos->cPiece (write-only, no reader anywhere). - Collapse WHITE/BLACK mirror-branches (castle-rights block, rook-trapped-in-corner) to color-indexed constants. - Close the PAWN_BIT..KING_BIT gap (bits 7-3 -> bits 4-0), removing the bvPattern >>= 3 before its KING_COUNTER_BY_ATTACK_PATTERN lookup. This also fixes a real bug introduced earlier this session when _WhoControlsSquareFast was converted to read these constants directly: g_SwapTable is only [32][32], but the old bit values (up to 0xF8) indexed far out of bounds on any attacked square -- data.c's InitializeSwapTable was always built assuming the bits 0-4 range this change now actually produces. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01XxmVi2sTMwpPp4i6WYFjan
Diffstat (limited to 'src/root.c')
-rwxr-xr-xsrc/root.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/root.c b/src/root.c
index 0ab42f7..d7113c0 100755
--- a/src/root.c
+++ b/src/root.c
@@ -460,6 +460,19 @@ Return value:
ASSERT(d);
n = (double)(ctx->sCounters.pawnhash.u64Hits);
Trace("Pawn hash hitrate: %5.3f percent.\n", (n/d) * 100.0);
+ // EXPERIMENTAL, measurement-only -- see eval.c's Eval() /
+ // rgKingSafetyHashProbe.
+ d = (double)(ctx->sCounters.kingsafetyhash.u64Probes) + 1;
+ ASSERT(d);
+ n = (double)(ctx->sCounters.kingsafetyhash.u64Hits);
+ Trace("[EXPERIMENTAL] King safety hash: %5.3f%% hitrate, "
+ "avg %.1f cyc hit / %.1f cyc miss (%" COMPILER_LONGLONG_UNSIGNED_FORMAT
+ " probes)\n",
+ (n/d) * 100.0,
+ (n > 0 ? (double)ctx->sCounters.kingsafetyhash.u64CyclesHit / n : 0.0),
+ ((d - 1 - n) > 0 ?
+ (double)ctx->sCounters.kingsafetyhash.u64CyclesMiss / (d - 1 - n) : 0.0),
+ ctx->sCounters.kingsafetyhash.u64Probes);
n = (double)(ctx->sCounters.tree.u64NullMoveSuccess);
d = (double)(ctx->sCounters.tree.u64NullMoves) + 1;
ASSERT(d);
@@ -615,6 +628,22 @@ Return value:
(u64Total ? (100.0 * (double)u64AttackPop / (double)u64Total) : 0.0),
(u64Total ? (100.0 * (double)u64Unaccounted / (double)u64Total) : 0.0));
{
+ UINT64 u64LazyDecision = ctx->sCounters.tree.u64CyclesEvalLazyDecision;
+ UINT64 u64CKSD = ctx->sCounters.tree.u64CyclesEvalCountKingSafetyDefects;
+ UINT64 u64Storm = ctx->sCounters.tree.u64CyclesEvalFileStormDefects;
+ UINT64 u64PreLazyRest = (u64PreLazyOther >= u64LazyDecision) ?
+ (u64PreLazyOther - u64LazyDecision) : 0;
+ Trace(" -- of which, pre-lazy breakdown --\n");
+ Trace(" material/passers/badtrades/bishoppairs: %5.1f%%\n",
+ (u64Total ? (100.0 * (double)u64PreLazyRest / (double)u64Total) : 0.0));
+ Trace(" lazy gate + EstimatePositionalScore: %5.1f%% "
+ "(of which CountKingSafetyDefects: %5.1f%%, "
+ "_GetFileStormDefects: %5.1f%%)\n",
+ (u64Total ? (100.0 * (double)u64LazyDecision / (double)u64Total) : 0.0),
+ (u64Total ? (100.0 * (double)u64CKSD / (double)u64Total) : 0.0),
+ (u64Total ? (100.0 * (double)u64Storm / (double)u64Total) : 0.0));
+ }
+ {
UINT64 u64PHits = ctx->sCounters.tree.u64CountEvalPawnsHit;
UINT64 u64PMisses = ctx->sCounters.tree.u64CountEvalPawnsMiss;
UINT64 u64PHitCycles = ctx->sCounters.tree.u64CyclesEvalPawnsHit;