Refactor accumulator storage/updates

Passed Non-regression STC:
LLR: 2.93 (-2.94,2.94) <-1.75,0.25>
Total: 115840 W: 29983 L: 29854 D: 56003
Ptnml(0-2): 338, 12990, 31149, 13091, 352
https://tests.stockfishchess.org/tests/view/67d0a044166a3e8781d84223

closes https://github.com/official-stockfish/Stockfish/pull/5927

No functional change
This commit is contained in:
Shawn Xu
2025-03-21 11:12:47 +01:00
committed by Disservin
parent 66aee01bb1
commit fc0e0a44d4
17 changed files with 813 additions and 527 deletions
+20 -27
View File
@@ -34,7 +34,6 @@
#include "bitboard.h"
#include "misc.h"
#include "movegen.h"
#include "nnue/nnue_common.h"
#include "syzygy/tbprobe.h"
#include "tt.h"
#include "uci.h"
@@ -83,7 +82,6 @@ std::ostream& operator<<(std::ostream& os, const Position& pos) {
if (int(Tablebases::MaxCardinality) >= popcount(pos.pieces()) && !pos.can_castle(ANY_CASTLING))
{
StateInfo st;
ASSERT_ALIGNED(&st, Eval::NNUE::CacheLineSize);
Position p;
p.set(pos.fen(), pos.is_chess960(), &st);
@@ -685,10 +683,10 @@ bool Position::gives_check(Move m) const {
// moves should be filtered out before this function is called.
// If a pointer to the TT table is passed, the entry for the new position
// will be prefetched
void Position::do_move(Move m,
StateInfo& newSt,
bool givesCheck,
const TranspositionTable* tt = nullptr) {
DirtyPiece Position::do_move(Move m,
StateInfo& newSt,
bool givesCheck,
const TranspositionTable* tt = nullptr) {
assert(m.is_ok());
assert(&newSt != st);
@@ -709,11 +707,7 @@ void Position::do_move(Move m,
++st->rule50;
++st->pliesFromNull;
// Used by NNUE
st->accumulatorBig.computed[WHITE] = st->accumulatorBig.computed[BLACK] =
st->accumulatorSmall.computed[WHITE] = st->accumulatorSmall.computed[BLACK] = false;
auto& dp = st->dirtyPiece;
DirtyPiece dp;
dp.dirty_num = 1;
Color us = sideToMove;
@@ -733,7 +727,7 @@ void Position::do_move(Move m,
assert(captured == make_piece(us, ROOK));
Square rfrom, rto;
do_castling<true>(us, from, to, rfrom, rto);
do_castling<true>(us, from, to, rfrom, rto, &dp);
k ^= Zobrist::psq[captured][rfrom] ^ Zobrist::psq[captured][rto];
st->nonPawnKey[us] ^= Zobrist::psq[captured][rfrom] ^ Zobrist::psq[captured][rto];
@@ -906,6 +900,8 @@ void Position::do_move(Move m,
}
assert(pos_is_ok());
return dp;
}
@@ -975,23 +971,25 @@ void Position::undo_move(Move m) {
// Helper used to do/undo a castling move. This is a bit
// tricky in Chess960 where from/to squares can overlap.
template<bool Do>
void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto) {
void Position::do_castling(
Color us, Square from, Square& to, Square& rfrom, Square& rto, DirtyPiece* const dp) {
bool kingSide = to > from;
rfrom = to; // Castling is encoded as "king captures friendly rook"
rto = relative_square(us, kingSide ? SQ_F1 : SQ_D1);
to = relative_square(us, kingSide ? SQ_G1 : SQ_C1);
assert(!Do || dp);
if (Do)
{
auto& dp = st->dirtyPiece;
dp.piece[0] = make_piece(us, KING);
dp.from[0] = from;
dp.to[0] = to;
dp.piece[1] = make_piece(us, ROOK);
dp.from[1] = rfrom;
dp.to[1] = rto;
dp.dirty_num = 2;
dp->piece[0] = make_piece(us, KING);
dp->from[0] = from;
dp->to[0] = to;
dp->piece[1] = make_piece(us, ROOK);
dp->from[1] = rfrom;
dp->to[1] = rto;
dp->dirty_num = 2;
}
// Remove both pieces first since squares could overlap in Chess960
@@ -1011,7 +1009,7 @@ void Position::do_null_move(StateInfo& newSt, const TranspositionTable& tt) {
assert(!checkers());
assert(&newSt != st);
std::memcpy(&newSt, st, offsetof(StateInfo, accumulatorBig));
std::memcpy(&newSt, st, sizeof(StateInfo));
newSt.previous = st;
st->next = &newSt;
@@ -1026,11 +1024,6 @@ void Position::do_null_move(StateInfo& newSt, const TranspositionTable& tt) {
st->key ^= Zobrist::side;
prefetch(tt.first_entry(key()));
st->dirtyPiece.dirty_num = 0;
st->dirtyPiece.piece[0] = NO_PIECE; // Avoid checks in UpdateAccumulator()
st->accumulatorBig.computed[WHITE] = st->accumulatorBig.computed[BLACK] =
st->accumulatorSmall.computed[WHITE] = st->accumulatorSmall.computed[BLACK] = false;
st->pliesFromNull = 0;
sideToMove = ~sideToMove;