From: Marco Costalba Date: Thu, 21 May 2009 14:41:31 +0000 (+0200) Subject: Enable POPCNT at runtime X-Git-Url: https://git.sesse.net/?p=stockfish;a=commitdiff_plain;h=e7d3a006cda7822517159cad0ef222eb7e46db00 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 --- diff --git a/src/bitcount.h b/src/bitcount.h index 12826a9f..40160633 100644 --- a/src/bitcount.h +++ b/src/bitcount.h @@ -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) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 35922281..78cefc45 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -268,11 +268,14 @@ namespace { uint8_t BitCount8Bit[256]; // Function prototypes - template + template + Value do_evaluate(const Position& pos, EvalInfo& ei, int threadID); + + template void evaluate_pieces(const Position& p, Color us, EvalInfo& ei); template<> - void evaluate_pieces(const Position& p, Color us, EvalInfo &ei); + void evaluate_pieces(const Position& p, Color us, EvalInfo &ei); void evaluate_passed_pawns(const Position &pos, EvalInfo &ei); void evaluate_trapped_bishop_a7h7(const Position &pos, Square s, Color us, @@ -295,11 +298,19 @@ namespace { //// 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 /// between them based on the remaining material. +Value evaluate(const Position& pos, EvalInfo& ei, int threadID) { + + return CpuHasPOPCNT ? do_evaluate(pos, ei, threadID) + : do_evaluate(pos, ei, threadID); +} + +namespace { -Value evaluate(const Position &pos, EvalInfo &ei, int threadID) { +template +Value do_evaluate(const Position& pos, EvalInfo& ei, int threadID) { assert(pos.is_ok()); assert(threadID >= 0 && threadID < THREAD_MAX); @@ -346,10 +357,10 @@ Value evaluate(const Position &pos, EvalInfo &ei, int threadID) { // Evaluate pieces for (Color c = WHITE; c <= BLACK; c++) { - evaluate_pieces(pos, c, ei); - evaluate_pieces(pos, c, ei); - evaluate_pieces(pos, c, ei); - evaluate_pieces(pos, c, ei); + evaluate_pieces(pos, c, ei); + evaluate_pieces(pos, c, ei); + evaluate_pieces(pos, c, ei); + evaluate_pieces(pos, c, ei); // Sum up all attacked squares 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 // the king safety evaluation. for (Color c = WHITE; c <= BLACK; c++) - evaluate_pieces(pos, c, ei); + evaluate_pieces(pos, c, ei); // Evaluate passed pawns. We evaluate passed pawns for both sides at once, // 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); } +} // namespace /// quick_evaluate() does a very approximate evaluation of the current position. /// 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 - template + template 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 }; @@ -548,15 +560,15 @@ namespace { ei.kingAttackersWeight[us] += AttackWeight[Piece]; Bitboard bb = (b & ei.attackedBy[them][KING]); if (bb) - ei.kingAdjacentZoneAttacksCount[us] += count_1s_max_15(bb); + ei.kingAdjacentZoneAttacksCount[us] += count_1s_max_15(bb); } // Remove squares protected by enemy pawns Bitboard bb = (b & ~ei.attackedBy[them][PAWN]); // Mobility - int mob = (Piece != QUEEN ? count_1s_max_15(bb & ~p.pieces_of_color(us)) - : count_1s(bb & ~p.pieces_of_color(us))); + int mob = (Piece != QUEEN ? count_1s_max_15(bb & ~p.pieces_of_color(us)) + : count_1s(bb & ~p.pieces_of_color(us))); ei.mgMobility += Sign[us] * MgBonus[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 // color. - template + template void evaluate_pieces(const Position& pos, Color us, EvalInfo& ei) { Bitboard b; @@ -609,7 +621,7 @@ namespace { b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.rooks_and_queens(us)); // Attacks, mobility and outposts - mob = evaluate_common(pos, b, us, ei, s); + mob = evaluate_common(pos, b, us, ei, s); // Special patterns: trapped bishops on a7/h7/a2/h2 // and trapped bishops on a1/h1/a8/h8 in Chess960. @@ -692,7 +704,7 @@ namespace { // color. template<> - void evaluate_pieces(const Position& p, Color us, EvalInfo& ei) { + void evaluate_pieces(const Position& p, Color us, EvalInfo& ei) { int shelter = 0, sign = Sign[us]; Square s = p.king_square(us);