1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-07-11 11:39:15 +00:00

Retire run-time detection of hardware POPCNT

It was meant to build a single binary optimized
for any kind of CPU: with and without hardware POPCNT.

This is a nice idea but in practice was never used, or
people builds binary with popcnt enabled or not, mainly
according to their type of CPU. And it was also never
used in the official Jim's builds where, in case, would
be easier for a number of reasons, do build two different
versions: with and without SEE42 support.

So retire this feature and simplify the code.

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
Marco Costalba 2011-12-30 11:30:26 +01:00
parent 20a6f99cdb
commit 0a6532a39d
6 changed files with 56 additions and 74 deletions

View file

@ -198,7 +198,7 @@ void bitboards_init() {
SquareDistance[s1][s2] = std::max(file_distance(s1, s2), rank_distance(s1, s2));
for (int i = 0; i < 64; i++)
if (!CpuIs64Bit) // Matt Taylor's folding trick for 32 bit systems
if (!Is64Bit) // Matt Taylor's folding trick for 32 bit systems
{
Bitboard b = 1ULL << i;
b ^= b - 1;
@ -321,7 +321,7 @@ namespace {
// the number of 1s of the mask. Hence we deduce the size of the shift to
// apply to the 64 or 32 bits word to get the index.
masks[s] = sliding_attacks(pt, s, 0) & ~edges;
shifts[s] = (CpuIs64Bit ? 64 : 32) - count_1s<CNT32_MAX15>(masks[s]);
shifts[s] = (Is64Bit ? 64 : 32) - count_1s<CNT32_MAX15>(masks[s]);
// Use Carry-Rippler trick to enumerate all subsets of masks[s] and
// store the corresponding sliding attacks bitboard in reference[].
@ -337,7 +337,7 @@ namespace {
if (s < SQ_H8)
attacks[s + 1] = attacks[s] + size;
booster = MagicBoosters[CpuIs64Bit][rank_of(s)];
booster = MagicBoosters[Is64Bit][rank_of(s)];
// Find a magic for square 's' picking up an (almost) random number
// until we find the one that passes the verification test.

View file

@ -225,28 +225,27 @@ namespace {
};
// Function prototypes
template<bool HasPopCnt, bool Trace>
template<bool Trace>
Value do_evaluate(const Position& pos, Value& margin);
template<Color Us, bool HasPopCnt>
template<Color Us>
void init_eval_info(const Position& pos, EvalInfo& ei);
template<Color Us, bool HasPopCnt, bool Trace>
template<Color Us, bool Trace>
Score evaluate_pieces_of_color(const Position& pos, EvalInfo& ei, Score& mobility);
template<Color Us, bool HasPopCnt, bool Trace>
template<Color Us, bool Trace>
Score evaluate_king(const Position& pos, EvalInfo& ei, Value margins[]);
template<Color Us>
Score evaluate_threats(const Position& pos, EvalInfo& ei);
template<Color Us, bool HasPopCnt>
template<Color Us>
int evaluate_space(const Position& pos, EvalInfo& ei);
template<Color Us>
Score evaluate_passed_pawns(const Position& pos, EvalInfo& ei);
template<bool HasPopCnt>
Score evaluate_unstoppable_pawns(const Position& pos, EvalInfo& ei);
inline Score apply_weight(Score v, Score weight);
@ -261,15 +260,11 @@ namespace {
/// evaluate() is the main evaluation function. It always computes two
/// values, an endgame score and a middle game score, and interpolates
/// between them based on the remaining material.
Value evaluate(const Position& pos, Value& margin) {
return CpuHasPOPCNT ? do_evaluate<true, false>(pos, margin)
: do_evaluate<false, false>(pos, margin);
}
Value evaluate(const Position& pos, Value& margin) { return do_evaluate<false>(pos, margin); }
namespace {
template<bool HasPopCnt, bool Trace>
template<bool Trace>
Value do_evaluate(const Position& pos, Value& margin) {
EvalInfo ei;
@ -304,19 +299,19 @@ Value do_evaluate(const Position& pos, Value& margin) {
score += ei.pi->pawns_value();
// Initialize attack and king safety bitboards
init_eval_info<WHITE, HasPopCnt>(pos, ei);
init_eval_info<BLACK, HasPopCnt>(pos, ei);
init_eval_info<WHITE>(pos, ei);
init_eval_info<BLACK>(pos, ei);
// Evaluate pieces and mobility
score += evaluate_pieces_of_color<WHITE, HasPopCnt, Trace>(pos, ei, mobilityWhite)
- evaluate_pieces_of_color<BLACK, HasPopCnt, Trace>(pos, ei, mobilityBlack);
score += evaluate_pieces_of_color<WHITE, Trace>(pos, ei, mobilityWhite)
- evaluate_pieces_of_color<BLACK, Trace>(pos, ei, mobilityBlack);
score += apply_weight(mobilityWhite - mobilityBlack, Weights[Mobility]);
// Evaluate kings after all other pieces because we need complete attack
// information when computing the king safety evaluation.
score += evaluate_king<WHITE, HasPopCnt, Trace>(pos, ei, margins)
- evaluate_king<BLACK, HasPopCnt, Trace>(pos, ei, margins);
score += evaluate_king<WHITE, Trace>(pos, ei, margins)
- evaluate_king<BLACK, Trace>(pos, ei, margins);
// Evaluate tactical threats, we need full attack information including king
score += evaluate_threats<WHITE>(pos, ei)
@ -328,12 +323,12 @@ Value do_evaluate(const Position& pos, Value& margin) {
// If one side has only a king, check whether exists any unstoppable passed pawn
if (!pos.non_pawn_material(WHITE) || !pos.non_pawn_material(BLACK))
score += evaluate_unstoppable_pawns<HasPopCnt>(pos, ei);
score += evaluate_unstoppable_pawns(pos, ei);
// Evaluate space for both sides, only in middle-game.
if (ei.mi->space_weight())
{
int s = evaluate_space<WHITE, HasPopCnt>(pos, ei) - evaluate_space<BLACK, HasPopCnt>(pos, ei);
int s = evaluate_space<WHITE>(pos, ei) - evaluate_space<BLACK>(pos, ei);
score += apply_weight(make_score(s * ei.mi->space_weight(), 0), Weights[Space]);
}
@ -375,9 +370,9 @@ Value do_evaluate(const Position& pos, Value& margin) {
trace_add(MOBILITY, apply_weight(mobilityWhite, Weights[Mobility]), apply_weight(mobilityBlack, Weights[Mobility]));
trace_add(THREAT, evaluate_threats<WHITE>(pos, ei), evaluate_threats<BLACK>(pos, ei));
trace_add(PASSED, evaluate_passed_pawns<WHITE>(pos, ei), evaluate_passed_pawns<BLACK>(pos, ei));
trace_add(UNSTOPPABLE, evaluate_unstoppable_pawns<false>(pos, ei));
Score w = make_score(ei.mi->space_weight() * evaluate_space<WHITE, false>(pos, ei), 0);
Score b = make_score(ei.mi->space_weight() * evaluate_space<BLACK, false>(pos, ei), 0);
trace_add(UNSTOPPABLE, evaluate_unstoppable_pawns(pos, ei));
Score w = make_score(ei.mi->space_weight() * evaluate_space<WHITE>(pos, ei), 0);
Score b = make_score(ei.mi->space_weight() * evaluate_space<BLACK>(pos, ei), 0);
trace_add(SPACE, apply_weight(w, Weights[Space]), apply_weight(b, Weights[Space]));
trace_add(TOTAL, score);
TraceStream << "\nUncertainty margin: White: " << to_cp(margins[WHITE])
@ -424,10 +419,10 @@ namespace {
// init_eval_info() initializes king bitboards for given color adding
// pawn attacks. To be done at the beginning of the evaluation.
template<Color Us, bool HasPopCnt>
template<Color Us>
void init_eval_info(const Position& pos, EvalInfo& ei) {
const BitCountType Max15 = HasPopCnt ? CNT_POPCNT : CpuIs64Bit ? CNT64_MAX15 : CNT32_MAX15;
const BitCountType Max15 = HasPopCnt ? CNT_POPCNT : Is64Bit ? CNT64_MAX15 : CNT32_MAX15;
const Color Them = (Us == WHITE ? BLACK : WHITE);
Bitboard b = ei.attackedBy[Them][KING] = pos.attacks_from<KING>(pos.king_square(Them));
@ -474,7 +469,7 @@ namespace {
// evaluate_pieces<>() assigns bonuses and penalties to the pieces of a given color
template<PieceType Piece, Color Us, bool HasPopCnt, bool Trace>
template<PieceType Piece, Color Us, bool Trace>
Score evaluate_pieces(const Position& pos, EvalInfo& ei, Score& mobility, Bitboard mobilityArea) {
Bitboard b;
@ -483,8 +478,8 @@ namespace {
File f;
Score score = SCORE_ZERO;
const BitCountType Full = HasPopCnt ? CNT_POPCNT : CpuIs64Bit ? CNT64 : CNT32;
const BitCountType Max15 = HasPopCnt ? CNT_POPCNT : CpuIs64Bit ? CNT64_MAX15 : CNT32_MAX15;
const BitCountType Full = HasPopCnt ? CNT_POPCNT : Is64Bit ? CNT64 : CNT32;
const BitCountType Max15 = HasPopCnt ? CNT_POPCNT : Is64Bit ? CNT64_MAX15 : CNT32_MAX15;
const Color Them = (Us == WHITE ? BLACK : WHITE);
const Square* pl = pos.piece_list(Us, Piece);
@ -644,7 +639,7 @@ namespace {
// evaluate_pieces_of_color<>() assigns bonuses and penalties to all the
// pieces of a given color.
template<Color Us, bool HasPopCnt, bool Trace>
template<Color Us, bool Trace>
Score evaluate_pieces_of_color(const Position& pos, EvalInfo& ei, Score& mobility) {
const Color Them = (Us == WHITE ? BLACK : WHITE);
@ -654,10 +649,10 @@ namespace {
// Do not include in mobility squares protected by enemy pawns or occupied by our pieces
const Bitboard mobilityArea = ~(ei.attackedBy[Them][PAWN] | pos.pieces(Us));
score += evaluate_pieces<KNIGHT, Us, HasPopCnt, Trace>(pos, ei, mobility, mobilityArea);
score += evaluate_pieces<BISHOP, Us, HasPopCnt, Trace>(pos, ei, mobility, mobilityArea);
score += evaluate_pieces<ROOK, Us, HasPopCnt, Trace>(pos, ei, mobility, mobilityArea);
score += evaluate_pieces<QUEEN, Us, HasPopCnt, Trace>(pos, ei, mobility, mobilityArea);
score += evaluate_pieces<KNIGHT, Us, Trace>(pos, ei, mobility, mobilityArea);
score += evaluate_pieces<BISHOP, Us, Trace>(pos, ei, mobility, mobilityArea);
score += evaluate_pieces<ROOK, Us, Trace>(pos, ei, mobility, mobilityArea);
score += evaluate_pieces<QUEEN, Us, Trace>(pos, ei, mobility, mobilityArea);
// Sum up all attacked squares
ei.attackedBy[Us][0] = ei.attackedBy[Us][PAWN] | ei.attackedBy[Us][KNIGHT]
@ -669,10 +664,10 @@ namespace {
// evaluate_king<>() assigns bonuses and penalties to a king of a given color
template<Color Us, bool HasPopCnt, bool Trace>
template<Color Us, bool Trace>
Score evaluate_king(const Position& pos, EvalInfo& ei, Value margins[]) {
const BitCountType Max15 = HasPopCnt ? CNT_POPCNT : CpuIs64Bit ? CNT64_MAX15 : CNT32_MAX15;
const BitCountType Max15 = HasPopCnt ? CNT_POPCNT : Is64Bit ? CNT64_MAX15 : CNT32_MAX15;
const Color Them = (Us == WHITE ? BLACK : WHITE);
Bitboard undefended, b, b1, b2, safe;
@ -882,10 +877,9 @@ namespace {
// evaluate_unstoppable_pawns() evaluates the unstoppable passed pawns for both sides, this is quite
// conservative and returns a winning score only when we are very sure that the pawn is winning.
template<bool HasPopCnt>
Score evaluate_unstoppable_pawns(const Position& pos, EvalInfo& ei) {
const BitCountType Max15 = HasPopCnt ? CNT_POPCNT : CpuIs64Bit ? CNT64_MAX15 : CNT32_MAX15;
const BitCountType Max15 = HasPopCnt ? CNT_POPCNT : Is64Bit ? CNT64_MAX15 : CNT32_MAX15;
Bitboard b, b2, blockers, supporters, queeningPath, candidates;
Square s, blockSq, queeningSquare;
@ -1049,10 +1043,10 @@ namespace {
// squares one, two or three squares behind a friendly pawn are counted
// twice. Finally, the space bonus is scaled by a weight taken from the
// material hash table. The aim is to improve play on game opening.
template<Color Us, bool HasPopCnt>
template<Color Us>
int evaluate_space(const Position& pos, EvalInfo& ei) {
const BitCountType Max15 = HasPopCnt ? CNT_POPCNT : CpuIs64Bit ? CNT64_MAX15 : CNT32_MAX15;
const BitCountType Max15 = HasPopCnt ? CNT_POPCNT : Is64Bit ? CNT64_MAX15 : CNT32_MAX15;
const Color Them = (Us == WHITE ? BLACK : WHITE);
// Find the safe squares for our pieces inside the area defined by
@ -1187,7 +1181,7 @@ std::string trace_evaluate(const Position& pos) {
TraceStream << std::showpoint << std::showpos << std::fixed << std::setprecision(2);
memset(TracedScores, 0, 2 * 16 * sizeof(Score));
do_evaluate<false, true>(pos, margin);
do_evaluate<true>(pos, margin);
totals = TraceStream.str();
TraceStream.str("");

View file

@ -21,11 +21,10 @@
#include <string>
#include "bitboard.h"
#include "evaluate.h"
#include "misc.h"
#include "position.h"
#include "thread.h"
#include "search.h"
#include "ucioption.h"
#include "thread.h"
using namespace std;
@ -44,11 +43,7 @@ int main(int argc, char* argv[]) {
if (argc < 2)
{
cout << engine_name() << " by " << engine_authors() << endl;
if (CpuHasPOPCNT)
cout << "Good! CPU has hardware POPCNT." << endl;
uci_loop(); // Enter the UCI loop and wait for user input
uci_loop();
}
else if (string(argv[1]) == "bench")
benchmark(argc, argv);

View file

@ -68,20 +68,21 @@ static const string AppTag = "";
const string engine_name() {
const string months("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec");
const string cpu64(CpuIs64Bit ? " 64bit" : "");
const string cpu64(Is64Bit ? " 64bit" : "");
const string popcnt(HasPopCnt ? " SSE4.2" : "");
if (!EngineVersion.empty())
return AppName + " " + EngineVersion + cpu64;
return AppName + " " + EngineVersion + cpu64 + popcnt;
stringstream s, date(__DATE__); // From compiler, format is "Sep 21 2008"
string month, day, year;
date >> month >> day >> year;
s << setfill('0') << AppName + " " + AppTag + " "
<< year.substr(2, 2) << setw(2)
<< (1 + months.find(month) / 4) << setw(2)
<< day << cpu64;
s << AppName + " " + AppTag + " "
<< setfill('0') << year.substr(2)
<< setw(2) << (1 + months.find(month) / 4)
<< setw(2) << day << cpu64 << popcnt;
return s.str();
}

View file

@ -116,7 +116,7 @@ template<Color Us>
Score PawnInfoTable::evaluate_pawns(const Position& pos, Bitboard ourPawns,
Bitboard theirPawns, PawnInfo* pi) {
const BitCountType Max15 = CpuIs64Bit ? CNT64_MAX15 : CNT32_MAX15;
const BitCountType Max15 = Is64Bit ? CNT64_MAX15 : CNT32_MAX15;
const Color Them = (Us == WHITE ? BLACK : WHITE);
Bitboard b;

View file

@ -124,30 +124,22 @@ inline void __cpuid(int CPUInfo[4], int)
#define FORCE_INLINE inline
#endif
/// cpu_has_popcnt() detects support for popcnt instruction at runtime
inline bool cpu_has_popcnt() {
int CPUInfo[4] = {-1};
__cpuid(CPUInfo, 0x00000001);
return (CPUInfo[2] >> 23) & 1;
}
/// CpuHasPOPCNT is a global constant initialized at startup that
/// is set to true if CPU on which application runs supports popcnt
/// hardware instruction. Unless USE_POPCNT is not defined.
/// HasPopCnt is a global constant initialized at compile time that is set to
/// true if CPU on which application runs supports popcnt hardware instruction.
#if defined(USE_POPCNT)
const bool CpuHasPOPCNT = cpu_has_popcnt();
const bool HasPopCnt = true;
#else
const bool CpuHasPOPCNT = false;
const bool HasPopCnt = false;
#endif
/// CpuIs64Bit is a global constant initialized at compile time that
/// is set to true if CPU on which application runs is a 64 bits.
/// Is64Bit is a global constant initialized at compile time that is set to
/// true if CPU on which application runs is a 64 bits.
#if defined(IS_64BIT)
const bool CpuIs64Bit = true;
const bool Is64Bit = true;
#else
const bool CpuIs64Bit = false;
const bool Is64Bit = false;
#endif
#include <string>