diff options
| author | Scott Gasch <[email protected]> | 2026-09-16 08:02:21 -0700 |
|---|---|---|
| committer | Scott Gasch <[email protected]> | 2026-09-16 08:02:21 -0700 |
| commit | 966a0ef4da9cf3911eb3da0533179199808717b4 (patch) | |
| tree | e09363b574215ef0d8996155a5ab24314db2dd69 /src/probe.c | |
| parent | b91c8453f3fe21c8ccd3568923d8e39141c9c945 (diff) | |
Retire cPawns/cNonPawns piece-location lists in favor of bbPawns/bbPieces/cKingSq, and hoist two redundant TotalNonPawnCount POPCNT calls out of per-node hot loops.
POSITION no longer stores cPawns[2][8], cNonPawns[2][16], uPawnCount[2],
uNonPawnCount[2][8], or uWhiteSqBishopCount[2] -- every reader now goes
through PawnMaterial/TotalNonPawnCount/WhiteSqBishopCount/KingPosition
(chess.h), computed from the already-incrementally-maintained bbPawns/
bbPieces/cKingSq bitboards via a single -mpopcnt POPCNT instead of a
stored counter. move.c's make/unmake loses the list-swap-on-removal
bookkeeping entirely. GNUmakefile now passes -mpopcnt so the popcount
builtins actually compile to one instruction instead of clang's ~15-op
SWAR fallback.
Measured a small but real nps regression from the naive swap (search.c's
QSearch move-filter and eval.c's _EvalKing were each recomputing the same
TotalNonPawnCount sum on every candidate move / twice per node); hoisted
both to a single call per node instead. Net result across a same-code
self-play match: ~1541.5 knps candidate vs ~1505.7 knps head_reference.
A third hoist (FindEnprisePiece out of SelectBestWithHistory) was tried
and reverted -- its cache isn't actually loop-invariant within a node
(populated from inside Eval(), which doesn't run before every selection
call), caught by a DEBUG-build ASSERT before it landed.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Diffstat (limited to 'src/probe.c')
| -rw-r--r-- | src/probe.c | 78 |
1 files changed, 53 insertions, 25 deletions
diff --git a/src/probe.c b/src/probe.c index 2d59e5a..5054142 100644 --- a/src/probe.c +++ b/src/probe.c @@ -33,6 +33,14 @@ Revision History: #include "chess.h" #include "fathom/tbprobe.h" +// See eval.c's identical comment: routes this file's Syzygy-bitboard- +// builder bitboard-scan loops to the inlined +// FastCoorFromBitBoardRank8ToRank1 (chess.h) instead of the real +// out-of-line extern call. +#ifndef CROUTINES +#define CoorFromBitBoardRank8ToRank1 FastCoorFromBitBoardRank8ToRank1 +#endif + ULONG g_uEgtbLock = 0; // @@ -147,9 +155,7 @@ Return value: **/ { ULONG uColor; - ULONG u; COOR c; - PIECE p; UINT64 bb; *pu64White = *pu64Black = 0ULL; @@ -160,37 +166,59 @@ Return value: { UINT64 *pu64Side = (uColor == WHITE) ? pu64White : pu64Black; - for (u = 0; u < pos->uPawnCount[uColor]; u++) { - c = pos->cPawns[uColor][u]; - ASSERT(IS_ON_BOARD(c)); - bb = (1ULL << (TO64(c))); - *pu64Side |= bb; - *pu64Pawns |= bb; + BITBOARD bbPawns = pos->bbPawns[uColor]; + + while (IS_ON_BOARD(c = CoorFromBitBoardRank8ToRank1(&bbPawns))) + { + bb = (1ULL << (TO64(c))); + *pu64Side |= bb; + *pu64Pawns |= bb; + } } - for (u = 0; u < pos->uNonPawnCount[uColor][0]; u++) { - c = pos->cNonPawns[uColor][u]; + c = KingPosition(pos, uColor); ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_KING(pos->rgSquare[c].pPiece)); bb = (1ULL << (TO64(c))); *pu64Side |= bb; + *pu64Kings |= bb; + } + + { + BITBOARD bbType; + COOR cType; + + bbType = pos->bbPieces[uColor][KNIGHT]; + while (IS_ON_BOARD(cType = CoorFromBitBoardRank8ToRank1(&bbType))) + { + bb = (1ULL << (TO64(cType))); + *pu64Side |= bb; + *pu64Knights |= bb; + } + + bbType = pos->bbPieces[uColor][BISHOP]; + while (IS_ON_BOARD(cType = CoorFromBitBoardRank8ToRank1(&bbType))) + { + bb = (1ULL << (TO64(cType))); + *pu64Side |= bb; + *pu64Bishops |= bb; + } - if (0 == u) + bbType = pos->bbPieces[uColor][ROOK]; + while (IS_ON_BOARD(cType = CoorFromBitBoardRank8ToRank1(&bbType))) { - ASSERT(IS_KING(pos->rgSquare[c].pPiece)); - *pu64Kings |= bb; - continue; + bb = (1ULL << (TO64(cType))); + *pu64Side |= bb; + *pu64Rooks |= bb; } - p = pos->rgSquare[c].pPiece; - ASSERT(p && !IS_PAWN(p) && !IS_KING(p)); - if (IS_KNIGHT(p)) *pu64Knights |= bb; - else if (IS_BISHOP(p)) *pu64Bishops |= bb; - else if (IS_ROOK(p)) *pu64Rooks |= bb; - else + bbType = pos->bbPieces[uColor][QUEEN]; + while (IS_ON_BOARD(cType = CoorFromBitBoardRank8ToRank1(&bbType))) { - ASSERT(IS_QUEEN(p)); + bb = (1ULL << (TO64(cType))); + *pu64Side |= bb; *pu64Queens |= bb; } } @@ -243,8 +271,8 @@ Return value: return(FALSE); } - wcount = pos->uNonPawnCount[WHITE][0] + pos->uPawnCount[WHITE]; - bcount = pos->uNonPawnCount[BLACK][0] + pos->uPawnCount[BLACK]; + wcount = TotalNonPawnCount(pos, WHITE) + FastCountBits(pos->bbPawns[WHITE]); + bcount = TotalNonPawnCount(pos, BLACK) + FastCountBits(pos->bbPawns[BLACK]); if ((wcount + bcount) > TB_LARGEST) { return(FALSE); @@ -384,8 +412,8 @@ Return value: return(FALSE); } - wcount = pos->uNonPawnCount[WHITE][0] + pos->uPawnCount[WHITE]; - bcount = pos->uNonPawnCount[BLACK][0] + pos->uPawnCount[BLACK]; + wcount = TotalNonPawnCount(pos, WHITE) + FastCountBits(pos->bbPawns[WHITE]); + bcount = TotalNonPawnCount(pos, BLACK) + FastCountBits(pos->bbPawns[BLACK]); if ((wcount + bcount) > TB_LARGEST) { return(FALSE); |
