1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-05-01 01:03:09 +00:00

Enable POPCNT at runtime

Runtime detect POPCNT instruction support and
use it.

Also if POPCNT is not supported we don't add _any_ overhead so
that we don't lose any speed in standard case.

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
Marco Costalba 2009-05-21 16:41:31 +02:00
parent 3376c68f4b
commit e7d3a006cd
2 changed files with 33 additions and 16 deletions

View file

@ -159,4 +159,9 @@ inline int count_1s_max_15(Bitboard b) {
} }
// Global variable initialized at startup that is set to true if
// CPU on which application runs support POPCNT intrinsic.
const bool CpuHasPOPCNT = cpu_has_popcnt();
#endif // !defined(BITCOUNT_H_INCLUDED) #endif // !defined(BITCOUNT_H_INCLUDED)

View file

@ -268,11 +268,14 @@ namespace {
uint8_t BitCount8Bit[256]; uint8_t BitCount8Bit[256];
// Function prototypes // Function prototypes
template<PieceType Piece> template<bool HasPopCnt>
Value do_evaluate(const Position& pos, EvalInfo& ei, int threadID);
template<PieceType Piece, bool HasPopCnt>
void evaluate_pieces(const Position& p, Color us, EvalInfo& ei); void evaluate_pieces(const Position& p, Color us, EvalInfo& ei);
template<> template<>
void evaluate_pieces<KING>(const Position& p, Color us, EvalInfo &ei); void evaluate_pieces<KING, false>(const Position& p, Color us, EvalInfo &ei);
void evaluate_passed_pawns(const Position &pos, EvalInfo &ei); void evaluate_passed_pawns(const Position &pos, EvalInfo &ei);
void evaluate_trapped_bishop_a7h7(const Position &pos, Square s, Color us, void evaluate_trapped_bishop_a7h7(const Position &pos, Square s, Color us,
@ -295,11 +298,19 @@ namespace {
//// Functions //// Functions
//// ////
/// evaluate() is the main evaluation function. It always computes two /// evaluate() is the main evaluation function. It always computes two
/// values, an endgame score and a middle game score, and interpolates /// values, an endgame score and a middle game score, and interpolates
/// between them based on the remaining material. /// between them based on the remaining material.
Value evaluate(const Position& pos, EvalInfo& ei, int threadID) {
Value evaluate(const Position &pos, EvalInfo &ei, int threadID) { return CpuHasPOPCNT ? do_evaluate<true>(pos, ei, threadID)
: do_evaluate<false>(pos, ei, threadID);
}
namespace {
template<bool HasPopCnt>
Value do_evaluate(const Position& pos, EvalInfo& ei, int threadID) {
assert(pos.is_ok()); assert(pos.is_ok());
assert(threadID >= 0 && threadID < THREAD_MAX); assert(threadID >= 0 && threadID < THREAD_MAX);
@ -346,10 +357,10 @@ Value evaluate(const Position &pos, EvalInfo &ei, int threadID) {
// Evaluate pieces // Evaluate pieces
for (Color c = WHITE; c <= BLACK; c++) for (Color c = WHITE; c <= BLACK; c++)
{ {
evaluate_pieces<KNIGHT>(pos, c, ei); evaluate_pieces<KNIGHT, HasPopCnt>(pos, c, ei);
evaluate_pieces<BISHOP>(pos, c, ei); evaluate_pieces<BISHOP, HasPopCnt>(pos, c, ei);
evaluate_pieces<ROOK>(pos, c, ei); evaluate_pieces<ROOK, HasPopCnt>(pos, c, ei);
evaluate_pieces<QUEEN>(pos, c, ei); evaluate_pieces<QUEEN, HasPopCnt>(pos, c, ei);
// Sum up all attacked squares // Sum up all attacked squares
ei.attackedBy[c][0] = ei.attackedBy[c][PAWN] | ei.attackedBy[c][KNIGHT] ei.attackedBy[c][0] = ei.attackedBy[c][PAWN] | ei.attackedBy[c][KNIGHT]
@ -361,7 +372,7 @@ Value evaluate(const Position &pos, EvalInfo &ei, int threadID) {
// because we need complete attack information for all pieces when computing // because we need complete attack information for all pieces when computing
// the king safety evaluation. // the king safety evaluation.
for (Color c = WHITE; c <= BLACK; c++) for (Color c = WHITE; c <= BLACK; c++)
evaluate_pieces<KING>(pos, c, ei); evaluate_pieces<KING, false>(pos, c, ei);
// Evaluate passed pawns. We evaluate passed pawns for both sides at once, // Evaluate passed pawns. We evaluate passed pawns for both sides at once,
// because we need to know which side promotes first in positions where // because we need to know which side promotes first in positions where
@ -437,6 +448,7 @@ Value evaluate(const Position &pos, EvalInfo &ei, int threadID) {
return (ei.mateThreat[stm] == MOVE_NONE ? v : 8 * QueenValueMidgame - v); return (ei.mateThreat[stm] == MOVE_NONE ? v : 8 * QueenValueMidgame - v);
} }
} // namespace
/// quick_evaluate() does a very approximate evaluation of the current position. /// quick_evaluate() does a very approximate evaluation of the current position.
/// It currently considers only material and piece square table scores. Perhaps /// It currently considers only material and piece square table scores. Perhaps
@ -528,7 +540,7 @@ namespace {
// evaluate_common() computes terms common to all pieces attack // evaluate_common() computes terms common to all pieces attack
template<PieceType Piece> template<PieceType Piece, bool HasPopCnt>
int evaluate_common(const Position& p, const Bitboard& b, Color us, EvalInfo& ei, Square s = SQ_NONE) { int evaluate_common(const Position& p, const Bitboard& b, Color us, EvalInfo& ei, Square s = SQ_NONE) {
static const int AttackWeight[] = { 0, 0, KnightAttackWeight, BishopAttackWeight, RookAttackWeight, QueenAttackWeight }; static const int AttackWeight[] = { 0, 0, KnightAttackWeight, BishopAttackWeight, RookAttackWeight, QueenAttackWeight };
@ -548,15 +560,15 @@ namespace {
ei.kingAttackersWeight[us] += AttackWeight[Piece]; ei.kingAttackersWeight[us] += AttackWeight[Piece];
Bitboard bb = (b & ei.attackedBy[them][KING]); Bitboard bb = (b & ei.attackedBy[them][KING]);
if (bb) if (bb)
ei.kingAdjacentZoneAttacksCount[us] += count_1s_max_15<false>(bb); ei.kingAdjacentZoneAttacksCount[us] += count_1s_max_15<HasPopCnt>(bb);
} }
// Remove squares protected by enemy pawns // Remove squares protected by enemy pawns
Bitboard bb = (b & ~ei.attackedBy[them][PAWN]); Bitboard bb = (b & ~ei.attackedBy[them][PAWN]);
// Mobility // Mobility
int mob = (Piece != QUEEN ? count_1s_max_15<false>(bb & ~p.pieces_of_color(us)) int mob = (Piece != QUEEN ? count_1s_max_15<HasPopCnt>(bb & ~p.pieces_of_color(us))
: count_1s<false>(bb & ~p.pieces_of_color(us))); : count_1s<HasPopCnt>(bb & ~p.pieces_of_color(us)));
ei.mgMobility += Sign[us] * MgBonus[Piece][mob]; ei.mgMobility += Sign[us] * MgBonus[Piece][mob];
ei.egMobility += Sign[us] * EgBonus[Piece][mob]; ei.egMobility += Sign[us] * EgBonus[Piece][mob];
@ -588,7 +600,7 @@ namespace {
// evaluate_pieces<>() assigns bonuses and penalties to the pieces of a given // evaluate_pieces<>() assigns bonuses and penalties to the pieces of a given
// color. // color.
template<PieceType Piece> template<PieceType Piece, bool HasPopCnt>
void evaluate_pieces(const Position& pos, Color us, EvalInfo& ei) { void evaluate_pieces(const Position& pos, Color us, EvalInfo& ei) {
Bitboard b; Bitboard b;
@ -609,7 +621,7 @@ namespace {
b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.rooks_and_queens(us)); b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.rooks_and_queens(us));
// Attacks, mobility and outposts // Attacks, mobility and outposts
mob = evaluate_common<Piece>(pos, b, us, ei, s); mob = evaluate_common<Piece, HasPopCnt>(pos, b, us, ei, s);
// Special patterns: trapped bishops on a7/h7/a2/h2 // Special patterns: trapped bishops on a7/h7/a2/h2
// and trapped bishops on a1/h1/a8/h8 in Chess960. // and trapped bishops on a1/h1/a8/h8 in Chess960.
@ -692,7 +704,7 @@ namespace {
// color. // color.
template<> template<>
void evaluate_pieces<KING>(const Position& p, Color us, EvalInfo& ei) { void evaluate_pieces<KING, false>(const Position& p, Color us, EvalInfo& ei) {
int shelter = 0, sign = Sign[us]; int shelter = 0, sign = Sign[us];
Square s = p.king_square(us); Square s = p.king_square(us);