Simplify bitboards

This PR:
- retires the unused distance() functions in bitboard.h including the 4K SquareDistance LUT,
- makes the 64K PopCnt16 LUT constexpr and only compiles it in if we don't use  a popcount intrinsic (we can't fully remove the LUT because it's faster than the intrinsic in the absence of a popcount machine instruction),
- retires Bitboards::init().

Passed STC:
https://tests.stockfishchess.org/tests/view/6a48e6d3f97ff95f78795a8f
LLR: 2.94 (-2.94,2.94) <-1.75,0.25>
Total: 162016 W: 42054 L: 41976 D: 77986
Ptnml(0-2): 383, 17375, 45454, 17373, 423

I didn't run LTC because the changes only really impact workers without popcount and there aren't any present on fishtest ATM. The correctness of the constexpr PopCnt16 LUT was verified locally with a x86-64 build; the build yields the same signature as master.

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

No functional change
This commit is contained in:
Guy Vreuls
2026-07-16 08:28:24 +02:00
committed by Joost VandeVondele
parent 1c384d3a87
commit 151e204cc8
4 changed files with 29 additions and 31 deletions
-10
View File
@@ -18,12 +18,8 @@
#include "bitboard.h"
#include <bitset>
namespace Stockfish {
u8 PopCnt16[1 << 16];
// Returns an ASCII representation of a bitboard suitable
// to be printed to standard output. Useful for debugging.
std::string Bitboards::pretty(Bitboard b) {
@@ -45,10 +41,4 @@ std::string Bitboards::pretty(Bitboard b) {
return s;
}
// Initializes the popcount table at startup.
void Bitboards::init() {
for (unsigned i = 0; i < (1 << 16); ++i)
PopCnt16[i] = u8(std::bitset<16>(i).count());
}
} // namespace Stockfish
+28 -18
View File
@@ -21,8 +21,8 @@
#include <algorithm>
#include <cassert>
#include <cstring>
#include <string>
#include <type_traits>
#include "types.h"
#include "misc.h"
@@ -31,7 +31,6 @@ namespace Stockfish {
namespace Bitboards {
void init();
std::string pretty(Bitboard b);
} // namespace Stockfish::Bitboards
@@ -63,8 +62,6 @@ constexpr Bitboard Rank6BB = Rank1BB << (8 * 5);
constexpr Bitboard Rank7BB = Rank1BB << (8 * 6);
constexpr Bitboard Rank8BB = Rank1BB << (8 * 7);
extern u8 PopCnt16[1 << 16];
constexpr Bitboard square_bb(Square s) {
assert(is_ok(s));
return 1ULL << s;
@@ -130,26 +127,39 @@ constexpr Bitboard pawn_single_push_bb(Color c, Bitboard b) {
return c == WHITE ? shift<NORTH>(b) : shift<SOUTH>(b);
}
inline int edge_distance(File f) { return std::min(f, File(FILE_H - f)); }
constexpr int edge_distance(File f) { return std::min(f, File(FILE_H - f)); }
constexpr int constexpr_popcount(Bitboard b) {
b = b - ((b >> 1) & 0x5555555555555555ULL);
b = (b & 0x3333333333333333ULL) + ((b >> 2) & 0x3333333333333333ULL);
b = (b + (b >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
return static_cast<int>((b * 0x0101010101010101ULL) >> 56);
template<typename T>
constexpr int constexpr_popcount(T v) {
static_assert(std::is_integral_v<T>, "constexpr_popcount is undefined for non-integral types");
if constexpr (sizeof(T) <= 8)
{
u64 b = static_cast<std::make_unsigned_t<T>>(v);
b = b - ((b >> 1) & 0x5555555555555555ULL);
b = (b & 0x3333333333333333ULL) + ((b >> 2) & 0x3333333333333333ULL);
b = (b + (b >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
return static_cast<int>((b * 0x0101010101010101ULL) >> 56);
}
else
{
int result = 0;
for (; v; v >>= static_cast<T>(1))
if (v & static_cast<T>(1))
++result;
return result;
}
}
// Counts the number of non-zero bits in a bitboard.
inline int popcount(Bitboard b) {
#ifndef USE_POPCNT
u16 indices[4];
std::memcpy(indices, &b, sizeof(b));
return PopCnt16[indices[0]] + PopCnt16[indices[1]] + PopCnt16[indices[2]]
+ PopCnt16[indices[3]];
#elif defined(_MSC_VER)
#ifdef _MSC_VER
return int(_mm_popcnt_u64(b));
-2
View File
@@ -21,7 +21,6 @@
#include <utility>
#include "attacks.h"
#include "bitboard.h"
#include "misc.h"
#include "position.h"
#include "tune.h"
@@ -40,7 +39,6 @@ __attribute__((used)) // keep main alive
int main(int argc, char* argv[]) {
std::cout << engine_info() << std::endl;
Bitboards::init();
Attacks::init();
Position::init();
+1 -1
View File
@@ -76,7 +76,7 @@
#define IS_64BIT
#endif
#if defined(USE_POPCNT) && defined(_MSC_VER)
#if defined(_MSC_VER)
#include <nmmintrin.h> // Microsoft header for _mm_popcnt_u64()
#endif