summaryrefslogtreecommitdiff
path: root/src/root.c
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2026-09-04 23:54:51 -0700
committerScott Gasch <[email protected]>2026-09-04 23:54:51 -0700
commit5883f5a64f4f464b877b7637b8e13c25f7d208fc (patch)
tree97951281d86a02254be5682356fa5b29a5076a56 /src/root.c
parent92fc41226f784b251f41eab7e75c13075e980a54 (diff)
Add Eval() bitboard-migration plan, per-term EVAL_TIME cycle breakdown, drop redundant pawn-location bitboard
board_representation/EVAL.md: rewritten migration plan for a bitboard-backed Eval() (mobility ray-walks + bvAttacks replacement), plus a performance-philosophy section recording the profiling-first, cut-aggressively-except-mobility/safety-awareness approach agreed on this session, and findings on CountKingSafetyDefects' structural inability to share bvAttacks-derived state with _EvalKing. EVAL_TIME per-term instrumentation (chess.h/eval.c/root.c): breaks the existing whole-Eval() cycle counter down by pawns/knight/bishop/ rook/queen/king, the always-paid pre-lazy-exit segment, and the full-eval-only post-lazy segment, printed alongside the existing "Avg. cpu cycles in eval" line. Diagnostic only (EVAL_TIME-gated), no effect on the normal release profile. Drop PAWN_HASH_ENTRY's bbPawnLocations[2]: it duplicated POSITION's own incrementally-maintained bbPawns[2], rebuilt bit-by-bit on every pawn-hash miss for no reason. eval.c now reads pos->bbPawns[] directly; removed a stale per-iteration invariant assert in _EvalPawns that only made sense when the bitboard was being built bit-by-bit in that same loop. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01P6g6iF6mD1Hau6nCZCzwYj
Diffstat (limited to 'src/root.c')
-rwxr-xr-xsrc/root.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/root.c b/src/root.c
index bfcf034..5ce4c9e 100755
--- a/src/root.c
+++ b/src/root.c
@@ -563,6 +563,58 @@ Return value:
#ifdef EVAL_TIME
n = (double)ctx->sCounters.tree.u64CyclesInEval;
Trace("Avg. cpu cycles in eval: %8.1f.\n", (n / d));
+ {
+ //
+ // Per-term breakdown of the average above -- board_
+ // representation/EVAL.md section 0b. "other" covers every
+ // term not individually timed (pawn structure detail beyond
+ // _EvalPawns' own bucket, bishop pairs, bad-trade/passer-race
+ // detection, lazy-eval margin estimation, etc.) computed as
+ // the remainder rather than its own counter, so this always
+ // sums exactly to the total above regardless of what future
+ // terms get their own bucket.
+ //
+ UINT64 u64Pawns = ctx->sCounters.tree.u64CyclesEvalPawns;
+ UINT64 u64Knight = ctx->sCounters.tree.u64CyclesEvalKnight;
+ UINT64 u64Bishop = ctx->sCounters.tree.u64CyclesEvalBishop;
+ UINT64 u64Rook = ctx->sCounters.tree.u64CyclesEvalRook;
+ UINT64 u64Queen = ctx->sCounters.tree.u64CyclesEvalQueen;
+ UINT64 u64King = ctx->sCounters.tree.u64CyclesEvalKing;
+ //
+ // u64PreLazy already contains u64Pawns as a subset (pawns
+ // runs nested inside the pre-lazy segment, not after it) --
+ // split it out here rather than double-counting both.
+ //
+ UINT64 u64PreLazy = ctx->sCounters.tree.u64CyclesEvalPreLazy;
+ UINT64 u64PreLazyOther = (u64PreLazy >= u64Pawns) ?
+ (u64PreLazy - u64Pawns) : 0;
+ UINT64 u64PostMisc = ctx->sCounters.tree.u64CyclesEvalPostLazyMisc;
+ UINT64 u64AttackPop = ctx->sCounters.tree.u64CyclesEvalAttackTablePop;
+ UINT64 u64Named = (u64PreLazy + u64Knight + u64Bishop +
+ u64Rook + u64Queen + u64King + u64PostMisc +
+ u64AttackPop);
+ UINT64 u64Total = ctx->sCounters.tree.u64CyclesInEval;
+ UINT64 u64Unaccounted = (u64Total >= u64Named) ?
+ (u64Total - u64Named) : 0;
+
+ Trace(" eval breakdown (%% of total cycles in eval):\n");
+ Trace(" pre-lazy (always paid): %5.1f%% "
+ "(of which pawns: %5.1f%%, other pre-lazy: %5.1f%%)\n",
+ (u64Total ? (100.0 * (double)u64PreLazy / (double)u64Total) : 0.0),
+ (u64Total ? (100.0 * (double)u64Pawns / (double)u64Total) : 0.0),
+ (u64Total ? (100.0 * (double)u64PreLazyOther / (double)u64Total) : 0.0));
+ Trace(" knight: %5.1f%% bishop: %5.1f%% rook: %5.1f%%\n",
+ (u64Total ? (100.0 * (double)u64Knight / (double)u64Total) : 0.0),
+ (u64Total ? (100.0 * (double)u64Bishop / (double)u64Total) : 0.0),
+ (u64Total ? (100.0 * (double)u64Rook / (double)u64Total) : 0.0));
+ Trace(" queen: %5.1f%% king: %5.1f%% post-lazy misc: %5.1f%%\n",
+ (u64Total ? (100.0 * (double)u64Queen / (double)u64Total) : 0.0),
+ (u64Total ? (100.0 * (double)u64King / (double)u64Total) : 0.0),
+ (u64Total ? (100.0 * (double)u64PostMisc / (double)u64Total) : 0.0));
+ Trace(" attack-table pop: %5.1f%% unaccounted: %5.1f%%\n",
+ (u64Total ? (100.0 * (double)u64AttackPop / (double)u64Total) : 0.0),
+ (u64Total ? (100.0 * (double)u64Unaccounted / (double)u64Total) : 0.0));
+ }
#endif
#endif
}