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:
parent
3376c68f4b
commit
e7d3a006cd
2 changed files with 33 additions and 16 deletions
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Reference in a new issue