summaryrefslogtreecommitdiff
path: root/src/testsup.c
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2026-09-16 08:02:21 -0700
committerScott Gasch <[email protected]>2026-09-16 08:02:21 -0700
commit966a0ef4da9cf3911eb3da0533179199808717b4 (patch)
treee09363b574215ef0d8996155a5ab24314db2dd69 /src/testsup.c
parentb91c8453f3fe21c8ccd3568923d8e39141c9c945 (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/testsup.c')
-rw-r--r--src/testsup.c59
1 files changed, 12 insertions, 47 deletions
diff --git a/src/testsup.c b/src/testsup.c
index 0cbc9a4..c5c62c2 100644
--- a/src/testsup.c
+++ b/src/testsup.c
@@ -67,7 +67,7 @@ void
GenerateRandomLegalPosition(POSITION *pos)
{
COOR c, c1;
- ULONG x, uIndex;
+ ULONG x;
ULONG uColor;
PIECE p;
ULONG u;
@@ -78,15 +78,7 @@ GenerateRandomLegalPosition(POSITION *pos)
// Clear the board
//
memset(pos, 0, sizeof(POSITION));
- for (u = 0; u < ARRAY_SIZE(pos->cPawns[WHITE]); u++)
- {
- pos->cPawns[WHITE][u] = pos->cPawns[BLACK][u] = ILLEGAL_COOR;
- }
-
- for (u = 0; u < ARRAY_SIZE(pos->cNonPawns[WHITE]); u++)
- {
- pos->cNonPawns[WHITE][u] = pos->cNonPawns[BLACK][u] = ILLEGAL_COOR;
- }
+ pos->cKingSq[WHITE] = pos->cKingSq[BLACK] = ILLEGAL_COOR;
// memset above zeroes cEpSquare to 0x00 (A8), a real on-board
// square, not the "no en passant" sentinel -- every random
@@ -112,10 +104,8 @@ GenerateRandomLegalPosition(POSITION *pos)
c = RANDOM_COOR;
ASSERT(IS_ON_BOARD(c));
pos->rgSquare[c].pPiece = WHITE_KING;
- ASSERT(pos->cNonPawns[WHITE][0] == ILLEGAL_COOR);
- pos->cNonPawns[WHITE][0] = c;
- pos->uNonPawnCount[WHITE][KING] = 1;
- pos->uNonPawnCount[WHITE][0] = 1;
+ ASSERT(pos->cKingSq[WHITE] == ILLEGAL_COOR);
+ pos->cKingSq[WHITE] = c;
pos->uNonPawnMaterial[WHITE] = VALUE_KING;
pos->bbOccupied |= COOR_TO_BB(c);
pos->bbOccupiedSide[WHITE] |= COOR_TO_BB(c);
@@ -127,10 +117,8 @@ GenerateRandomLegalPosition(POSITION *pos)
while(DISTANCE(c, c1) < 2);
ASSERT(IS_ON_BOARD(c1));
pos->rgSquare[c1].pPiece = BLACK_KING;
- ASSERT(pos->cNonPawns[BLACK][0] == ILLEGAL_COOR);
- pos->cNonPawns[BLACK][0] = c1;
- pos->uNonPawnCount[BLACK][KING] = 1;
- pos->uNonPawnCount[BLACK][0] = 1;
+ ASSERT(pos->cKingSq[BLACK] == ILLEGAL_COOR);
+ pos->cKingSq[BLACK] = c1;
pos->uNonPawnMaterial[BLACK] = VALUE_KING;
pos->bbOccupied |= COOR_TO_BB(c1);
pos->bbOccupiedSide[BLACK] |= COOR_TO_BB(c1);
@@ -169,20 +157,12 @@ GenerateRandomLegalPosition(POSITION *pos)
ASSERT(GET_COLOR(p) == uColor);
if (IS_PAWN(p) &&
- (pos->uPawnCount[uColor] < 8) &&
- (!RANK1(c)) &&
+ (FastCountBits(pos->bbPawns[uColor]) < 8) &&
+ (!RANK1(c)) &&
(!RANK8(c)))
{
- //
- // The pawn list is not ordered at all, add
- // the new pawn's location to the list and
- // point from the pawn to the list.
- //
- pos->cPawns[uColor][pos->uPawnCount[uColor]] = c;
- pos->rgSquare[c].uIndex = pos->uPawnCount[uColor];
+ pos->rgSquare[c].uIndex = INVALID_PIECE_INDEX;
pos->rgSquare[c].pPiece = p;
- pos->uPawnCount[uColor]++;
- pos->uPawnMaterial[uColor] += VALUE_PAWN;
pos->bbPawns[uColor] |= COOR_TO_BB(c);
pos->bbOccupied |= COOR_TO_BB(c);
pos->bbOccupiedSide[uColor] |= COOR_TO_BB(c);
@@ -191,23 +171,12 @@ GenerateRandomLegalPosition(POSITION *pos)
else if (!IS_KING(p) &&
(IS_VALID_PIECE(p)))
{
- uIndex = pos->uNonPawnCount[uColor][0];
- pos->cNonPawns[uColor][uIndex] = c;
- pos->uNonPawnCount[uColor][0]++;
- pos->uNonPawnCount[uColor][PIECE_TYPE(p)]++;
pos->rgSquare[c].pPiece = p;
- pos->rgSquare[c].uIndex = uIndex;
+ pos->rgSquare[c].uIndex = INVALID_PIECE_INDEX;
pos->uNonPawnMaterial[uColor] += PIECE_VALUE(p);
pos->bbPieces[uColor][PIECE_TYPE(p)] |= COOR_TO_BB(c);
pos->bbOccupied |= COOR_TO_BB(c);
pos->bbOccupiedSide[uColor] |= COOR_TO_BB(c);
- if (IS_BISHOP(p))
- {
- if (IS_WHITE_SQUARE_COOR(c))
- {
- pos->uWhiteSqBishopCount[uColor]++;
- }
- }
break;
}
}
@@ -216,19 +185,15 @@ GenerateRandomLegalPosition(POSITION *pos)
} // next piece
} // next color
- ASSERT(pos->uNonPawnCount[WHITE][KING] == 1);
- ASSERT(pos->uNonPawnCount[BLACK][KING] == 1);
- //pos->uNonPawnCount[WHITE][0]--;
- //pos->uNonPawnCount[BLACK][0]--;
//
// Do the rest of the position
//
pos->iMaterialBalance[WHITE] =
((SCORE)(pos->uNonPawnMaterial[WHITE] +
- pos->uPawnMaterial[WHITE]) -
+ PawnMaterial(pos, WHITE)) -
(SCORE)(pos->uNonPawnMaterial[BLACK] +
- pos->uPawnMaterial[BLACK]));
+ PawnMaterial(pos, BLACK)));
pos->iMaterialBalance[BLACK] = -pos->iMaterialBalance[WHITE];
pos->uToMove = RANDOM_COLOR;
pos->uFifty = rand() % 100;