mirror of
https://github.com/sockspls/badfish
synced 2025-05-01 09:13:08 +00:00
Use incremental updates more often
Use incremental updates for accumulators for up to 2 plies. Do not copy accumulator. About 2% speedup. Passed STC: LLR: 2.95 (-2.94,2.94) {-0.25,1.25} Total: 21752 W: 2583 L: 2403 D: 16766 Ptnml(0-2): 128, 1761, 6923, 1931, 133 https://tests.stockfishchess.org/tests/view/5f7150cf3b22d6afa5069412 closes https://github.com/official-stockfish/Stockfish/pull/3157 No functional change
This commit is contained in:
parent
1dbd2a1ad5
commit
c065abdcaf
4 changed files with 87 additions and 30 deletions
|
@ -61,11 +61,8 @@ namespace Eval::NNUE::Features {
|
||||||
const PositionType& pos, TriggerEvent trigger,
|
const PositionType& pos, TriggerEvent trigger,
|
||||||
IndexListType removed[2], IndexListType added[2], bool reset[2]) {
|
IndexListType removed[2], IndexListType added[2], bool reset[2]) {
|
||||||
|
|
||||||
const auto& dp = pos.state()->dirtyPiece;
|
auto collect_for_one = [&](const DirtyPiece& dp) {
|
||||||
if (dp.dirty_num == 0) return;
|
|
||||||
|
|
||||||
for (Color perspective : { WHITE, BLACK }) {
|
for (Color perspective : { WHITE, BLACK }) {
|
||||||
reset[perspective] = false;
|
|
||||||
switch (trigger) {
|
switch (trigger) {
|
||||||
case TriggerEvent::kFriendKingMoved:
|
case TriggerEvent::kFriendKingMoved:
|
||||||
reset[perspective] = dp.piece[0] == make_piece(perspective, KING);
|
reset[perspective] = dp.piece[0] == make_piece(perspective, KING);
|
||||||
|
@ -79,10 +76,56 @@ namespace Eval::NNUE::Features {
|
||||||
pos, trigger, perspective, &added[perspective]);
|
pos, trigger, perspective, &added[perspective]);
|
||||||
} else {
|
} else {
|
||||||
Derived::CollectChangedIndices(
|
Derived::CollectChangedIndices(
|
||||||
pos, trigger, perspective,
|
pos, dp, trigger, perspective,
|
||||||
&removed[perspective], &added[perspective]);
|
&removed[perspective], &added[perspective]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto collect_for_two = [&](const DirtyPiece& dp1, const DirtyPiece& dp2) {
|
||||||
|
for (Color perspective : { WHITE, BLACK }) {
|
||||||
|
switch (trigger) {
|
||||||
|
case TriggerEvent::kFriendKingMoved:
|
||||||
|
reset[perspective] = dp1.piece[0] == make_piece(perspective, KING)
|
||||||
|
|| dp2.piece[0] == make_piece(perspective, KING);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (reset[perspective]) {
|
||||||
|
Derived::CollectActiveIndices(
|
||||||
|
pos, trigger, perspective, &added[perspective]);
|
||||||
|
} else {
|
||||||
|
Derived::CollectChangedIndices(
|
||||||
|
pos, dp1, trigger, perspective,
|
||||||
|
&removed[perspective], &added[perspective]);
|
||||||
|
Derived::CollectChangedIndices(
|
||||||
|
pos, dp2, trigger, perspective,
|
||||||
|
&removed[perspective], &added[perspective]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (pos.state()->previous->accumulator.computed_accumulation) {
|
||||||
|
const auto& prev_dp = pos.state()->dirtyPiece;
|
||||||
|
if (prev_dp.dirty_num == 0) return;
|
||||||
|
collect_for_one(prev_dp);
|
||||||
|
} else {
|
||||||
|
const auto& prev_dp = pos.state()->previous->dirtyPiece;
|
||||||
|
if (prev_dp.dirty_num == 0) {
|
||||||
|
const auto& prev2_dp = pos.state()->dirtyPiece;
|
||||||
|
if (prev2_dp.dirty_num == 0) return;
|
||||||
|
collect_for_one(prev2_dp);
|
||||||
|
} else {
|
||||||
|
const auto& prev2_dp = pos.state()->dirtyPiece;
|
||||||
|
if (prev2_dp.dirty_num == 0) {
|
||||||
|
collect_for_one(prev_dp);
|
||||||
|
} else {
|
||||||
|
collect_for_two(prev_dp, prev2_dp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -115,11 +158,11 @@ namespace Eval::NNUE::Features {
|
||||||
|
|
||||||
// Get a list of indices for recently changed features
|
// Get a list of indices for recently changed features
|
||||||
static void CollectChangedIndices(
|
static void CollectChangedIndices(
|
||||||
const Position& pos, const TriggerEvent trigger, const Color perspective,
|
const Position& pos, const DirtyPiece& dp, const TriggerEvent trigger, const Color perspective,
|
||||||
IndexList* const removed, IndexList* const added) {
|
IndexList* const removed, IndexList* const added) {
|
||||||
|
|
||||||
if (FeatureType::kRefreshTrigger == trigger) {
|
if (FeatureType::kRefreshTrigger == trigger) {
|
||||||
FeatureType::AppendChangedIndices(pos, perspective, removed, added);
|
FeatureType::AppendChangedIndices(pos, dp, perspective, removed, added);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,11 +52,10 @@ namespace Eval::NNUE::Features {
|
||||||
// Get a list of indices for recently changed features
|
// Get a list of indices for recently changed features
|
||||||
template <Side AssociatedKing>
|
template <Side AssociatedKing>
|
||||||
void HalfKP<AssociatedKing>::AppendChangedIndices(
|
void HalfKP<AssociatedKing>::AppendChangedIndices(
|
||||||
const Position& pos, Color perspective,
|
const Position& pos, const DirtyPiece& dp, Color perspective,
|
||||||
IndexList* removed, IndexList* added) {
|
IndexList* removed, IndexList* added) {
|
||||||
|
|
||||||
Square ksq = orient(perspective, pos.square<KING>(perspective));
|
Square ksq = orient(perspective, pos.square<KING>(perspective));
|
||||||
const auto& dp = pos.state()->dirtyPiece;
|
|
||||||
for (int i = 0; i < dp.dirty_num; ++i) {
|
for (int i = 0; i < dp.dirty_num; ++i) {
|
||||||
Piece pc = dp.piece[i];
|
Piece pc = dp.piece[i];
|
||||||
if (type_of(pc) == KING) continue;
|
if (type_of(pc) == KING) continue;
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace Eval::NNUE::Features {
|
||||||
IndexList* active);
|
IndexList* active);
|
||||||
|
|
||||||
// Get a list of indices for recently changed features
|
// Get a list of indices for recently changed features
|
||||||
static void AppendChangedIndices(const Position& pos, Color perspective,
|
static void AppendChangedIndices(const Position& pos, const DirtyPiece& dp, Color perspective,
|
||||||
IndexList* removed, IndexList* added);
|
IndexList* removed, IndexList* added);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -127,9 +127,14 @@ namespace Eval::NNUE {
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
const auto prev = now->previous;
|
const auto prev = now->previous;
|
||||||
if (prev && prev->accumulator.computed_accumulation) {
|
if (prev) {
|
||||||
|
if (prev->accumulator.computed_accumulation) {
|
||||||
UpdateAccumulator(pos);
|
UpdateAccumulator(pos);
|
||||||
return true;
|
return true;
|
||||||
|
} else if (prev->previous && prev->previous->accumulator.computed_accumulation) {
|
||||||
|
UpdateAccumulator(pos);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -289,11 +294,21 @@ namespace Eval::NNUE {
|
||||||
// Calculate cumulative value using difference calculation
|
// Calculate cumulative value using difference calculation
|
||||||
void UpdateAccumulator(const Position& pos) const {
|
void UpdateAccumulator(const Position& pos) const {
|
||||||
|
|
||||||
const auto prev_accumulator = pos.state()->previous->accumulator;
|
Accumulator* prev_accumulator;
|
||||||
|
assert(pos.state()->previous);
|
||||||
|
if (pos.state()->previous->accumulator.computed_accumulation) {
|
||||||
|
prev_accumulator = &pos.state()->previous->accumulator;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert(pos.state()->previous->previous);
|
||||||
|
assert(pos.state()->previous->previous->accumulator.computed_accumulation);
|
||||||
|
prev_accumulator = &pos.state()->previous->previous->accumulator;
|
||||||
|
}
|
||||||
|
|
||||||
auto& accumulator = pos.state()->accumulator;
|
auto& accumulator = pos.state()->accumulator;
|
||||||
IndexType i = 0;
|
IndexType i = 0;
|
||||||
Features::IndexList removed_indices[2], added_indices[2];
|
Features::IndexList removed_indices[2], added_indices[2];
|
||||||
bool reset[2];
|
bool reset[2] = { false, false };
|
||||||
RawFeatures::AppendChangedIndices(pos, kRefreshTriggers[i],
|
RawFeatures::AppendChangedIndices(pos, kRefreshTriggers[i],
|
||||||
removed_indices, added_indices, reset);
|
removed_indices, added_indices, reset);
|
||||||
|
|
||||||
|
@ -311,7 +326,7 @@ namespace Eval::NNUE {
|
||||||
acc[k] = biasesTile[k];
|
acc[k] = biasesTile[k];
|
||||||
} else {
|
} else {
|
||||||
auto prevAccTile = reinterpret_cast<const vec_t*>(
|
auto prevAccTile = reinterpret_cast<const vec_t*>(
|
||||||
&prev_accumulator.accumulation[perspective][i][j * kTileHeight]);
|
&prev_accumulator->accumulation[perspective][i][j * kTileHeight]);
|
||||||
for (IndexType k = 0; k < kNumRegs; ++k)
|
for (IndexType k = 0; k < kNumRegs; ++k)
|
||||||
acc[k] = vec_load(&prevAccTile[k]);
|
acc[k] = vec_load(&prevAccTile[k]);
|
||||||
|
|
||||||
|
@ -350,7 +365,7 @@ namespace Eval::NNUE {
|
||||||
kHalfDimensions * sizeof(BiasType));
|
kHalfDimensions * sizeof(BiasType));
|
||||||
} else {
|
} else {
|
||||||
std::memcpy(accumulator.accumulation[perspective][i],
|
std::memcpy(accumulator.accumulation[perspective][i],
|
||||||
prev_accumulator.accumulation[perspective][i],
|
prev_accumulator->accumulation[perspective][i],
|
||||||
kHalfDimensions * sizeof(BiasType));
|
kHalfDimensions * sizeof(BiasType));
|
||||||
// Difference calculation for the deactivated features
|
// Difference calculation for the deactivated features
|
||||||
for (const auto index : removed_indices[perspective]) {
|
for (const auto index : removed_indices[perspective]) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue