mirror of
https://github.com/official-stockfish/Stockfish.git
synced 2026-07-22 12:47:08 +00:00
Improve index generation
The speedup seems to vary by machine. The indexing function can be changed w/o needing to understand intrinsics. Result of 100 runs ================== base (...ish_baseline) = 1719637 +/- 3233 test (./stockfish ) = 1734245 +/- 3534 diff = +14608 +/- 4868 speedup = +0.0085 P(speedup > 0) = 1.0000 closes https://github.com/official-stockfish/Stockfish/pull/6366 No functional change
This commit is contained in:
committed by
Joost VandeVondele
parent
3bb01ce7a9
commit
6764561916
@@ -18,9 +18,9 @@
|
|||||||
|
|
||||||
#include "nnue_accumulator.h"
|
#include "nnue_accumulator.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <initializer_list>
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include "../bitboard.h"
|
#include "../bitboard.h"
|
||||||
@@ -362,6 +362,29 @@ void update_accumulator_incremental(
|
|||||||
(target_state.acc<TransformedFeatureDimensions>()).computed[Perspective] = true;
|
(target_state.acc<TransformedFeatureDimensions>()).computed[Perspective] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bitboard get_changed_pieces(const Piece old[SQUARE_NB], const Piece new_[SQUARE_NB]) {
|
||||||
|
#if defined(USE_AVX512) || defined(USE_AVX2)
|
||||||
|
static_assert(sizeof(Piece) == 1);
|
||||||
|
Bitboard same_bb = 0;
|
||||||
|
for (int i = 0; i < 64; i += 32)
|
||||||
|
{
|
||||||
|
const __m256i old_v = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(old + i));
|
||||||
|
const __m256i new_v = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(new_ + i));
|
||||||
|
const __m256i cmp_equal = _mm256_cmpeq_epi8(old_v, new_v);
|
||||||
|
const std::uint32_t equal_mask = _mm256_movemask_epi8(cmp_equal);
|
||||||
|
same_bb |= static_cast<Bitboard>(equal_mask) << i;
|
||||||
|
}
|
||||||
|
return ~same_bb;
|
||||||
|
#else
|
||||||
|
Bitboard changed = 0;
|
||||||
|
for (Square sq = SQUARE_ZERO; sq < SQUARE_NB; ++sq)
|
||||||
|
{
|
||||||
|
changed |= static_cast<Bitboard>(old[sq] != new_[sq]) << sq;
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
template<Color Perspective, IndexType Dimensions>
|
template<Color Perspective, IndexType Dimensions>
|
||||||
void update_accumulator_refresh_cache(const FeatureTransformer<Dimensions>& featureTransformer,
|
void update_accumulator_refresh_cache(const FeatureTransformer<Dimensions>& featureTransformer,
|
||||||
const Position& pos,
|
const Position& pos,
|
||||||
@@ -374,29 +397,24 @@ void update_accumulator_refresh_cache(const FeatureTransformer<Dimensions>& feat
|
|||||||
auto& entry = cache[ksq][Perspective];
|
auto& entry = cache[ksq][Perspective];
|
||||||
FeatureSet::IndexList removed, added;
|
FeatureSet::IndexList removed, added;
|
||||||
|
|
||||||
for (Color c : {WHITE, BLACK})
|
const Bitboard changed_bb = get_changed_pieces(entry.pieces, pos.piece_array());
|
||||||
{
|
Bitboard removed_bb = changed_bb & entry.pieceBB;
|
||||||
for (PieceType pt = PAWN; pt <= KING; ++pt)
|
Bitboard added_bb = changed_bb & pos.pieces();
|
||||||
{
|
|
||||||
const Piece piece = make_piece(c, pt);
|
|
||||||
const Bitboard oldBB = entry.byColorBB[c] & entry.byTypeBB[pt];
|
|
||||||
const Bitboard newBB = pos.pieces(c, pt);
|
|
||||||
Bitboard toRemove = oldBB & ~newBB;
|
|
||||||
Bitboard toAdd = newBB & ~oldBB;
|
|
||||||
|
|
||||||
while (toRemove)
|
while (removed_bb)
|
||||||
{
|
{
|
||||||
Square sq = pop_lsb(toRemove);
|
Square sq = pop_lsb(removed_bb);
|
||||||
removed.push_back(FeatureSet::make_index<Perspective>(sq, piece, ksq));
|
removed.push_back(FeatureSet::make_index<Perspective>(sq, entry.pieces[sq], ksq));
|
||||||
}
|
}
|
||||||
while (toAdd)
|
while (added_bb)
|
||||||
{
|
{
|
||||||
Square sq = pop_lsb(toAdd);
|
Square sq = pop_lsb(added_bb);
|
||||||
added.push_back(FeatureSet::make_index<Perspective>(sq, piece, ksq));
|
added.push_back(FeatureSet::make_index<Perspective>(sq, pos.piece_on(sq), ksq));
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entry.pieceBB = pos.pieces();
|
||||||
|
std::copy_n(pos.piece_array(), SQUARE_NB, entry.pieces);
|
||||||
|
|
||||||
auto& accumulator = accumulatorState.acc<Dimensions>();
|
auto& accumulator = accumulatorState.acc<Dimensions>();
|
||||||
accumulator.computed[Perspective] = true;
|
accumulator.computed[Perspective] = true;
|
||||||
|
|
||||||
@@ -518,12 +536,6 @@ void update_accumulator_refresh_cache(const FeatureTransformer<Dimensions>& feat
|
|||||||
std::memcpy(accumulator.psqtAccumulation[Perspective], entry.psqtAccumulation,
|
std::memcpy(accumulator.psqtAccumulation[Perspective], entry.psqtAccumulation,
|
||||||
sizeof(int32_t) * PSQTBuckets);
|
sizeof(int32_t) * PSQTBuckets);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (Color c : {WHITE, BLACK})
|
|
||||||
entry.byColorBB[c] = pos.pieces(c);
|
|
||||||
|
|
||||||
for (PieceType pt = PAWN; pt <= KING; ++pt)
|
|
||||||
entry.byTypeBB[pt] = pos.pieces(pt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ struct AccumulatorCaches {
|
|||||||
struct alignas(CacheLineSize) Entry {
|
struct alignas(CacheLineSize) Entry {
|
||||||
BiasType accumulation[Size];
|
BiasType accumulation[Size];
|
||||||
PSQTWeightType psqtAccumulation[PSQTBuckets];
|
PSQTWeightType psqtAccumulation[PSQTBuckets];
|
||||||
Bitboard byColorBB[COLOR_NB];
|
Piece pieces[SQUARE_NB];
|
||||||
Bitboard byTypeBB[PIECE_TYPE_NB];
|
Bitboard pieceBB;
|
||||||
|
|
||||||
// To initialize a refresh entry, we set all its bitboards empty,
|
// To initialize a refresh entry, we set all its bitboards empty,
|
||||||
// so we put the biases in the accumulation, without any weights on top
|
// so we put the biases in the accumulation, without any weights on top
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ class Position {
|
|||||||
template<typename... PieceTypes>
|
template<typename... PieceTypes>
|
||||||
Bitboard pieces(Color c, PieceTypes... pts) const;
|
Bitboard pieces(Color c, PieceTypes... pts) const;
|
||||||
Piece piece_on(Square s) const;
|
Piece piece_on(Square s) const;
|
||||||
|
const Piece* piece_array() const;
|
||||||
Square ep_square() const;
|
Square ep_square() const;
|
||||||
bool empty(Square s) const;
|
bool empty(Square s) const;
|
||||||
template<PieceType Pt>
|
template<PieceType Pt>
|
||||||
@@ -208,6 +209,8 @@ inline Piece Position::piece_on(Square s) const {
|
|||||||
return board[s];
|
return board[s];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const Piece* Position::piece_array() const { return board; }
|
||||||
|
|
||||||
inline bool Position::empty(Square s) const { return piece_on(s) == NO_PIECE; }
|
inline bool Position::empty(Square s) const { return piece_on(s) == NO_PIECE; }
|
||||||
|
|
||||||
inline Piece Position::moved_piece(Move m) const { return piece_on(m.from_sq()); }
|
inline Piece Position::moved_piece(Move m) const { return piece_on(m.from_sq()); }
|
||||||
|
|||||||
Reference in New Issue
Block a user