mirror of
https://github.com/sockspls/badfish
synced 2025-07-11 19:49:14 +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:
parent
20a6f99cdb
commit
0a6532a39d
6 changed files with 56 additions and 74 deletions
|
@ -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.
|
||||
|
|
|
@ -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("");
|
||||
|
|
11
src/main.cpp
11
src/main.cpp
|
@ -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);
|
||||
|
|
13
src/misc.cpp
13
src/misc.cpp
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
24
src/types.h
24
src/types.h
|
@ -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>
|
||||
|
|
Loading…
Add table
Reference in a new issue