mirror of
https://github.com/official-stockfish/Stockfish.git
synced 2026-07-22 12:47:08 +00:00
Precompute moves and use magics index as compress mask on AVX512ICL
Passed STC https://tests.stockfishchess.org/tests/view/69f6df65b64b50e29dbed427 LLR: 2.94 (-2.94,2.94) <0.00,2.00> Total: 112224 W: 29195 L: 28782 D: 54247 Ptnml(0-2): 312, 12345, 30381, 12766, 308 Local speedup: ``` Result of 100 runs base (...kfish.master) = 2050387 +/- 5497 test (./stockfish ) = 2069598 +/- 4426 diff = +19211 +/- 7468 speedup = +0.0094 P(speedup > 0) = 1.0000 ``` closes https://github.com/official-stockfish/Stockfish/pull/6797 No functional change
This commit is contained in:
committed by
Joost VandeVondele
parent
ab8f901d25
commit
1554a2ca0b
@@ -281,6 +281,17 @@ inline int popcount(Bitboard b) {
|
||||
#endif
|
||||
}
|
||||
|
||||
inline constexpr int lsb_index64[64] = {
|
||||
0, 47, 1, 56, 48, 27, 2, 60, 57, 49, 41, 37, 28, 16, 3, 61, 54, 58, 35, 52, 50, 42,
|
||||
21, 44, 38, 32, 29, 23, 17, 11, 4, 62, 46, 55, 26, 59, 40, 36, 15, 53, 34, 51, 20, 43,
|
||||
31, 22, 10, 45, 25, 39, 14, 33, 19, 30, 9, 24, 13, 18, 8, 12, 7, 6, 5, 63};
|
||||
|
||||
constexpr int constexpr_lsb(uint64_t bb) {
|
||||
assert(bb != 0);
|
||||
constexpr uint64_t debruijn64 = 0x03F79D71B4CB0A89ULL;
|
||||
return lsb_index64[((bb ^ (bb - 1)) * debruijn64) >> 58];
|
||||
}
|
||||
|
||||
// Returns the least significant bit in a non-zero bitboard.
|
||||
inline Square lsb(Bitboard b) {
|
||||
assert(b);
|
||||
|
||||
+85
-4
@@ -62,6 +62,76 @@ inline Move* splat_moves(Move* moveList, Square from, Bitboard to_bb) {
|
||||
return moveList + popcount(to_bb);
|
||||
}
|
||||
|
||||
// Rook/bishop, indexed by (Pt - BISHOP) and from sq
|
||||
// Moves are provided in ascending order of the piece's attacks on an empty board
|
||||
alignas(64) constexpr auto SliderMoves = []() {
|
||||
std::array<std::array<std::array<Move, 16>, SQUARE_NB>, 2> arr{};
|
||||
for (PieceType pt : {BISHOP, ROOK})
|
||||
{
|
||||
for (Square s = SQ_A1; s <= SQ_H8; ++s)
|
||||
{
|
||||
Bitboard bb = PseudoAttacks[pt][s];
|
||||
int i = 0;
|
||||
while (bb)
|
||||
{
|
||||
arr[pt - BISHOP][s][i++] = Move(s, Square(constexpr_lsb(bb)));
|
||||
bb &= bb - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}();
|
||||
|
||||
// Knight/king analog of the above
|
||||
alignas(64) constexpr auto KnightKingMoves = []() {
|
||||
std::array<std::array<std::array<Move, 8>, SQUARE_NB>, 2> arr{};
|
||||
for (PieceType pt : {KNIGHT, KING})
|
||||
{
|
||||
for (Square s = SQ_A1; s <= SQ_H8; ++s)
|
||||
{
|
||||
Bitboard bb = PseudoAttacks[pt][s];
|
||||
int i = 0;
|
||||
while (bb)
|
||||
{
|
||||
arr[pt == KING][s][i++] = Move(s, Square(constexpr_lsb(bb)));
|
||||
bb &= bb - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}();
|
||||
|
||||
template<PieceType Pt>
|
||||
inline Move*
|
||||
splat_precomputed_moves(Move* moveList, Square from, Bitboard occupied, Bitboard target) {
|
||||
static_assert(Pt != QUEEN && Pt != PAWN, "Unsupported piece type");
|
||||
|
||||
// The nth bit in the mask corresponds to the nth square in the piece's pseudo-attacks
|
||||
uint32_t mask;
|
||||
if constexpr (Pt == BISHOP || Pt == ROOK)
|
||||
{
|
||||
const Magic& magic = Magics[from][Pt - BISHOP];
|
||||
|
||||
mask = magic.attacks[magic.index(occupied)];
|
||||
mask &= pext(target, magic.pseudoAttacks);
|
||||
|
||||
const __m256i moves =
|
||||
*reinterpret_cast<const __m256i*>(SliderMoves[Pt - BISHOP][from].data());
|
||||
_mm256_storeu_si256(reinterpret_cast<__m256i*>(moveList),
|
||||
_mm256_maskz_compress_epi16(mask, moves));
|
||||
}
|
||||
else
|
||||
{
|
||||
mask = pext(target, PseudoAttacks[Pt][from]);
|
||||
|
||||
__m128i moves = *reinterpret_cast<const __m128i*>(KnightKingMoves[Pt == KING][from].data());
|
||||
_mm_storeu_si128(reinterpret_cast<__m128i*>(moveList),
|
||||
_mm_maskz_compress_epi16(mask, moves));
|
||||
}
|
||||
|
||||
return moveList + popcount(mask);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<Direction offset>
|
||||
@@ -192,8 +262,15 @@ Move* generate_moves(const Position& pos, Move* moveList, Bitboard target) {
|
||||
|
||||
while (bb)
|
||||
{
|
||||
Square from = pop_lsb(bb);
|
||||
Bitboard b = attacks_bb<Pt>(from, pos.pieces()) & target;
|
||||
Square from = pop_lsb(bb);
|
||||
#ifdef USE_AVX512ICL
|
||||
if constexpr (Pt != QUEEN)
|
||||
{
|
||||
moveList = splat_precomputed_moves<Pt>(moveList, from, pos.pieces(), target);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
Bitboard b = attacks_bb<Pt>(from, pos.pieces()) & target;
|
||||
|
||||
moveList = splat_moves(moveList, from, b);
|
||||
}
|
||||
@@ -225,9 +302,13 @@ Move* generate_all(const Position& pos, Move* moveList) {
|
||||
moveList = generate_moves<Us, QUEEN>(pos, moveList, target);
|
||||
}
|
||||
|
||||
Bitboard b = attacks_bb<KING>(ksq) & (Type == EVASIONS ? ~pos.pieces(Us) : target);
|
||||
Bitboard b = Type == EVASIONS ? ~pos.pieces(Us) : target;
|
||||
|
||||
moveList = splat_moves(moveList, ksq, b);
|
||||
#ifdef USE_AVX512ICL
|
||||
moveList = splat_precomputed_moves<KING>(moveList, ksq, 0ULL, b);
|
||||
#else
|
||||
moveList = splat_moves(moveList, ksq, attacks_bb<KING>(ksq) & b);
|
||||
#endif
|
||||
|
||||
if ((Type == QUIETS || Type == NON_EVASIONS) && pos.can_castle(Us & ANY_CASTLING))
|
||||
for (CastlingRights cr : {Us & KING_SIDE, Us & QUEEN_SIDE})
|
||||
|
||||
@@ -38,19 +38,6 @@
|
||||
|
||||
namespace Stockfish::Eval::NNUE::Layers {
|
||||
|
||||
#if (USE_SSSE3 | (USE_NEON >= 8))
|
||||
static constexpr int lsb_index64[64] = {
|
||||
0, 47, 1, 56, 48, 27, 2, 60, 57, 49, 41, 37, 28, 16, 3, 61, 54, 58, 35, 52, 50, 42,
|
||||
21, 44, 38, 32, 29, 23, 17, 11, 4, 62, 46, 55, 26, 59, 40, 36, 15, 53, 34, 51, 20, 43,
|
||||
31, 22, 10, 45, 25, 39, 14, 33, 19, 30, 9, 24, 13, 18, 8, 12, 7, 6, 5, 63};
|
||||
|
||||
constexpr int constexpr_lsb(uint64_t bb) {
|
||||
assert(bb != 0);
|
||||
constexpr uint64_t debruijn64 = 0x03F79D71B4CB0A89ULL;
|
||||
return lsb_index64[((bb ^ (bb - 1)) * debruijn64) >> 58];
|
||||
}
|
||||
#endif
|
||||
|
||||
// Sparse input implementation
|
||||
template<IndexType InDims, IndexType OutDims>
|
||||
class AffineTransformSparseInput {
|
||||
|
||||
Reference in New Issue
Block a user