| Age | Commit message (Collapse) | Author |
|
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
|
|
Board-representation migration, sections 2-3 (GetAttacks half):
- board.c: VerifyPositionConsistency's bbPieces consistency check
(migration section 2), verified clean via gmake TEST=1 with the
assert live.
- POSITION.bbPawns[2]: new incrementally-maintained per-color pawn
location bitboard (chess.h), maintained at the same 6 move.c sites
as bbPieces, populated from scratch in fen.c. Distinct from the
pawn-hash-keyed bbPawnLocations; this one needs no
SEARCHER_THREAD_CONTEXT, so it's reachable from GetAttacks's actual
call sites (which only ever have a POSITION*).
- data.c/chess.h/main.c: g_RookRayAll/g_BishopRayAll (all 4 per-square
ray directions pre-ORed) and g_PawnAttackOriginBB[2][128] startup
tables, plus FastFirstBit/FastLastBit (static inline bsf/bsr
wrappers, chess.h) -- supporting tables/helpers for the primitive
below.
- see.c: _WhoAttacksSquareBB (bitboard "who attacks square X" query)
and _GetAttacksBB (SEE_LIST-populating PoC wrapping it), side by
side with the existing SlowGetAttacks/asm GetAttacks -- not wired
into the GetAttacks macro yet (section 6), pure addition.
- testsee.c: SeeListsAreEqual made order-independent (SEE() sorts the
list right after GetAttacks returns, so order was never semantically
significant); TestGetAttacks extended to run _GetAttacksBB as a
third comparison across the existing 20,000-random-position sweep;
added an interleaved asm/Slow/BB cycles-per-call benchmark across
opening/middlegame/endgame positions.
- testsup.c: fixed GenerateRandomLegalPosition (used by the sweep
above) to maintain bbPieces/bbPawns at its two hand-placement sites
-- a latent gap since section 1 that made its own
VerifyPositionConsistency legality gate almost always reject
generated positions, causing large, variable retry-loop slowdowns.
Verified: 20,000-position x every-square x both-colors correctness
sweep passes (gmake TEST=1), precommit_check.sh clean (self-test +
DEBUG smoke test). Benchmark: _GetAttacksBB is ~0.53-0.55x asm
GetAttacks's cycles/call (opening/middlegame) and ~0.89x (endgame) --
faster, not just equivalent, primarily from replacing bbOccupied's
up-to-16-iteration pawn loop with two bbPawns ORs, plus a
g_PawnAttackOriginBB table lookup replacing per-call pawn-delta
arithmetic and per-direction/per-side-group early-outs in the slider
walk. See board_representation/MIGRATION.md section 3 for the full
writeup, including a reverted approach that measured slower and why,
and the CountKingSafetyDefects half's re-scoped (not yet implemented)
design.
Also confirmed (not caused by this work, not fixed here): a
pre-existing non-deterministic MP-race assertion in util.c:1093's PV
printing, reproduced independently on a clean HEAD checkout.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Jntky4yGUTyQVaGCXms4F2
|
|
bitboard helpers
- bitboard.c: CoorFromBitBoardRank1ToRank8 cleared the lowest set bit
unconditionally instead of the reported (highest) one, silently
mis-walking doubled-pawn files in eval.c's passed-pawn detection.
- search.c/searchsup.c: move GetLMRReduction's precondition checks from
inside the function to the caller in search.c (pre-existing work),
finishing the split with a matching gate in split.c's HelpSearch --
the parallel-search call site had no gate at all, letting it call
GetLMRReduction unconditionally (including for checking moves),
reachable only under real multithreading (--cpus > 1) and the
intermittent root cause of assertion crashes seen under --cpus 4.
- eval.c: redirect CountBits/CoorFromBitBoardRank8ToRank1/
CoorFromBitBoardRank1ToRank8 to inline compiler-builtin versions
(gated !CROUTINES) instead of the real out-of-line asm calls, on
eval.c's ~20 existing production call sites. CountBits' asm body
isn't O(1) popcnt, it's a Kernighan bit-clearing loop plus call
overhead, paid on every Eval() call.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Jntky4yGUTyQVaGCXms4F2
|
|
|