From a87ea9846d4adc8d2ed8107c072c43b5ef53e4fe Mon Sep 17 00:00:00 2001 From: Marco Costalba Date: Fri, 3 Jul 2009 08:28:13 +0100 Subject: [PATCH] Use bsfq asm instruction to count bits On 64 bit systems we can use bsfq instruction to count set bits in a bitboard. This is a patch for GCC and Intel compilers to take advantage of that and get a 2% speed up. Original patch from Heinz van Saanen, adapted to current tree by me. No functional change. Signed-off-by: Marco Costalba --- src/bitboard.cpp | 10 +++++----- src/bitboard.h | 26 +++++++++++++++++++++----- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/bitboard.cpp b/src/bitboard.cpp index ba03d66e..0bdb9d3a 100644 --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@ -161,7 +161,7 @@ const int RShift[64] = { 21, 22, 22, 22, 22, 22, 22, 21, 20, 21, 21, 21, 21, 21, 21, 20 }; -#endif +#endif // defined(IS_64BIT) Bitboard RMask[64]; @@ -245,16 +245,16 @@ void init_bitboards() { /// pop_1st_bit() finds and clears the least significant nonzero bit in a /// nonzero bitboard. -#if defined(IS_64BIT) +#if defined(IS_64BIT) && !defined(USE_BSFQ) -Square pop_1st_bit(Bitboard *b) { +Square pop_1st_bit(Bitboard* b) { Bitboard bb = *b ^ (*b - 1); uint32_t fold = int(bb) ^ int(bb >> 32); *b &= (*b - 1); return Square(BitTable[(fold * 0x783a9b23) >> 26]); } -#else +#elif !defined(USE_BSFQ) // Use type-punning union b_union { @@ -267,7 +267,7 @@ union b_union { }; // WARNING: Needs -fno-strict-aliasing compiler option -Square pop_1st_bit(Bitboard *bb) { +Square pop_1st_bit(Bitboard* bb) { b_union u; uint32_t b; diff --git a/src/bitboard.h b/src/bitboard.h index 3429c42e..d5c16a91 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -36,6 +36,11 @@ #define IS_64BIT #endif +#if defined(IS_64BIT) && (defined(__GNUC__) || defined(__INTEL_COMPILER)) +#define USE_BSFQ +#endif + + //// //// Includes //// @@ -383,14 +388,24 @@ inline Bitboard isolated_pawn_mask(Square s) { /// first_1() finds the least significant nonzero bit in a nonzero bitboard. +/// pop_1st_bit() finds and clears the least significant nonzero bit in a +/// nonzero bitboard. -#if defined(IS_64BIT) +#if defined(USE_BSFQ) // Assembly code by Heinz van Saanen -inline Square first_1(Bitboard b) { - return Square(BitTable[((b & -b) * 0x218a392cd3d5dbfULL) >> 58]); +inline Square __attribute__((always_inline)) first_1(Bitboard b) { + Bitboard dummy; + __asm__("bsfq %1, %0": "=r"(dummy): "rm"(b) ); + return (Square)(dummy); +} + +inline Square __attribute__((always_inline)) pop_1st_bit(Bitboard* b) { + const Square s = first_1(*b); + *b &= ~(1ULL<> 26]); } +extern Square pop_1st_bit(Bitboard* b); + #endif @@ -407,7 +424,6 @@ inline Square first_1(Bitboard b) { extern void print_bitboard(Bitboard b); extern void init_bitboards(); -extern Square pop_1st_bit(Bitboard *b); #endif // !defined(BITBOARD_H_INCLUDED) -- 2.39.2