mirror of
https://github.com/opelly27/Stockfish.git
synced 2026-05-20 12:07:43 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 86c2d2fc3b | |||
| f9d3b48ad0 | |||
| d720778b2b | |||
| e2880f9b8e | |||
| 909e3adede | |||
| 626b1f8c6a | |||
| 06a350f1ae | |||
| a9e9746495 |
+2
-1
@@ -27,7 +27,8 @@
|
|||||||
|
|
||||||
enum Depth {
|
enum Depth {
|
||||||
DEPTH_ZERO = 0,
|
DEPTH_ZERO = 0,
|
||||||
DEPTH_MAX = 200 // 100 * OnePly;
|
DEPTH_MAX = 200, // 100 * OnePly;
|
||||||
|
DEPTH_ENSURE_SIGNED = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+10
-56
@@ -41,20 +41,20 @@
|
|||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "bitcount.h"
|
#include "bitcount.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "thread.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
/// Version number. If this is left empty, the current date (in the format
|
/// Version number. If this is left empty, the current date (in the format
|
||||||
/// YYMMDD) is used as a version number.
|
/// YYMMDD) is used as a version number.
|
||||||
|
|
||||||
static const string EngineVersion = "1.7";
|
static const string EngineVersion = "1.7.1";
|
||||||
static const string AppName = "Stockfish";
|
static const string AppName = "Stockfish";
|
||||||
static const string AppTag = "";
|
static const string AppTag = "";
|
||||||
|
|
||||||
@@ -183,85 +183,39 @@ int get_system_time() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// builtin_cpu_count() tries to detect the number of CPU cores, if
|
/// cpu_count() tries to detect the number of CPU cores.
|
||||||
/// hyper-threading is enabled this is the number of logical processors.
|
|
||||||
|
|
||||||
#if !defined(_MSC_VER)
|
#if !defined(_MSC_VER)
|
||||||
|
|
||||||
# if defined(_SC_NPROCESSORS_ONLN)
|
# if defined(_SC_NPROCESSORS_ONLN)
|
||||||
static int builtin_cpu_count() {
|
int cpu_count() {
|
||||||
return Min(sysconf(_SC_NPROCESSORS_ONLN), 8);
|
return Min(sysconf(_SC_NPROCESSORS_ONLN), MAX_THREADS);
|
||||||
}
|
}
|
||||||
# elif defined(__hpux)
|
# elif defined(__hpux)
|
||||||
static int builtin_cpu_count() {
|
int cpu_count() {
|
||||||
struct pst_dynamic psd;
|
struct pst_dynamic psd;
|
||||||
if (pstat_getdynamic(&psd, sizeof(psd), (size_t)1, 0) == -1)
|
if (pstat_getdynamic(&psd, sizeof(psd), (size_t)1, 0) == -1)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return Min(psd.psd_proc_cnt, 8);
|
return Min(psd.psd_proc_cnt, MAX_THREADS);
|
||||||
}
|
}
|
||||||
# else
|
# else
|
||||||
static int builtin_cpu_count() {
|
int cpu_count() {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static int builtin_cpu_count() {
|
int cpu_count() {
|
||||||
SYSTEM_INFO s;
|
SYSTEM_INFO s;
|
||||||
GetSystemInfo(&s);
|
GetSystemInfo(&s);
|
||||||
return Min(s.dwNumberOfProcessors, 8);
|
return Min(s.dwNumberOfProcessors, MAX_THREADS);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/// HT_enabled() returns true if hyper-threading is enabled on current machine
|
|
||||||
|
|
||||||
static bool HT_enabled() {
|
|
||||||
|
|
||||||
char CPUString[0x20];
|
|
||||||
int CPUInfo[4] = {-1};
|
|
||||||
int nIds, nLogicalCPU, nCores;
|
|
||||||
|
|
||||||
// Detect CPU producer
|
|
||||||
__cpuid(CPUInfo, 0);
|
|
||||||
nIds = CPUInfo[0];
|
|
||||||
|
|
||||||
memset(CPUString, 0, sizeof(CPUString));
|
|
||||||
memcpy(&CPUString[0], &CPUInfo[1], sizeof(int));
|
|
||||||
memcpy(&CPUString[4], &CPUInfo[3], sizeof(int));
|
|
||||||
memcpy(&CPUString[8], &CPUInfo[2], sizeof(int));
|
|
||||||
|
|
||||||
// Not an Intel CPU or CPUID.4 not supported
|
|
||||||
if (strcmp(CPUString, "GenuineIntel") || nIds < 4)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Detect if HT Technology is supported
|
|
||||||
__cpuid(CPUInfo, 1);
|
|
||||||
if (!((CPUInfo[3] >> 28) & 1))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
nLogicalCPU = (CPUInfo[1] >> 16) & 0xFF;
|
|
||||||
|
|
||||||
// Detect number of cores
|
|
||||||
__cpuid(CPUInfo, 4);
|
|
||||||
nCores = 1 + ((CPUInfo[0] >> 26) & 0x3F);
|
|
||||||
|
|
||||||
return nLogicalCPU > nCores;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// cpu_count() tries to detect the number of physical CPU cores taking
|
|
||||||
/// in account hyper-threading.
|
|
||||||
|
|
||||||
int cpu_count() {
|
|
||||||
|
|
||||||
return HT_enabled() ? builtin_cpu_count() / 2 : builtin_cpu_count();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
From Beowulf, from Olithink
|
From Beowulf, from Olithink
|
||||||
*/
|
*/
|
||||||
|
|||||||
+15
-10
@@ -257,7 +257,7 @@ namespace {
|
|||||||
int SearchStartTime, MaxNodes, MaxDepth, MaxSearchTime;
|
int SearchStartTime, MaxNodes, MaxDepth, MaxSearchTime;
|
||||||
int AbsoluteMaxSearchTime, ExtraSearchTime, ExactMaxTime;
|
int AbsoluteMaxSearchTime, ExtraSearchTime, ExactMaxTime;
|
||||||
bool UseTimeManagement, InfiniteSearch, PonderSearch, StopOnPonderhit;
|
bool UseTimeManagement, InfiniteSearch, PonderSearch, StopOnPonderhit;
|
||||||
bool FirstRootMove, AbortSearch, Quit, AspirationFailLow;
|
bool FirstRootMove, AbortSearch, Quit, AspirationFailLow, ZugDetection;
|
||||||
|
|
||||||
// Log file
|
// Log file
|
||||||
bool UseLogFile;
|
bool UseLogFile;
|
||||||
@@ -294,7 +294,7 @@ namespace {
|
|||||||
Depth extension(const Position&, Move, bool, bool, bool, bool, bool, bool*);
|
Depth extension(const Position&, Move, bool, bool, bool, bool, bool, bool*);
|
||||||
bool ok_to_do_nullmove(const Position& pos);
|
bool ok_to_do_nullmove(const Position& pos);
|
||||||
bool ok_to_prune(const Position& pos, Move m, Move threat);
|
bool ok_to_prune(const Position& pos, Move m, Move threat);
|
||||||
bool ok_to_use_TT(const TTEntry* tte, Depth depth, Value beta, int ply);
|
bool ok_to_use_TT(const TTEntry* tte, Depth depth, Value beta, int ply, bool allowNullmove);
|
||||||
Value refine_eval(const TTEntry* tte, Value defaultEval, int ply);
|
Value refine_eval(const TTEntry* tte, Value defaultEval, int ply);
|
||||||
void update_history(const Position& pos, Move move, Depth depth, Move movesSearched[], int moveCount);
|
void update_history(const Position& pos, Move move, Depth depth, Move movesSearched[], int moveCount);
|
||||||
void update_killers(Move m, SearchStack& ss);
|
void update_killers(Move m, SearchStack& ss);
|
||||||
@@ -425,6 +425,7 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move,
|
|||||||
MultiPV = get_option_value_int("MultiPV");
|
MultiPV = get_option_value_int("MultiPV");
|
||||||
Chess960 = get_option_value_bool("UCI_Chess960");
|
Chess960 = get_option_value_bool("UCI_Chess960");
|
||||||
UseLogFile = get_option_value_bool("Use Search Log");
|
UseLogFile = get_option_value_bool("Use Search Log");
|
||||||
|
ZugDetection = get_option_value_bool("Zugzwang detection"); // To be removed after 1.7.1
|
||||||
|
|
||||||
if (UseLogFile)
|
if (UseLogFile)
|
||||||
LogFile.open(get_option_value_string("Search Log Filename").c_str(), std::ios::out | std::ios::app);
|
LogFile.open(get_option_value_string("Search Log Filename").c_str(), std::ios::out | std::ios::app);
|
||||||
@@ -1299,7 +1300,7 @@ namespace {
|
|||||||
tte = TT.retrieve(posKey);
|
tte = TT.retrieve(posKey);
|
||||||
ttMove = (tte ? tte->move() : MOVE_NONE);
|
ttMove = (tte ? tte->move() : MOVE_NONE);
|
||||||
|
|
||||||
if (tte && ok_to_use_TT(tte, depth, beta, ply))
|
if (tte && ok_to_use_TT(tte, depth, beta, ply, allowNullmove))
|
||||||
{
|
{
|
||||||
ss[ply].currentMove = ttMove; // Can be MOVE_NONE
|
ss[ply].currentMove = ttMove; // Can be MOVE_NONE
|
||||||
return value_from_tt(tte->value(), ply);
|
return value_from_tt(tte->value(), ply);
|
||||||
@@ -1388,7 +1389,7 @@ namespace {
|
|||||||
{
|
{
|
||||||
assert(value_to_tt(nullValue, ply) == nullValue);
|
assert(value_to_tt(nullValue, ply) == nullValue);
|
||||||
|
|
||||||
TT.store(posKey, nullValue, VALUE_TYPE_LOWER, depth, MOVE_NONE);
|
TT.store(posKey, nullValue, VALUE_TYPE_NS_LO, depth, MOVE_NONE);
|
||||||
return nullValue;
|
return nullValue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1625,7 +1626,7 @@ namespace {
|
|||||||
tte = TT.retrieve(pos.get_key());
|
tte = TT.retrieve(pos.get_key());
|
||||||
ttMove = (tte ? tte->move() : MOVE_NONE);
|
ttMove = (tte ? tte->move() : MOVE_NONE);
|
||||||
|
|
||||||
if (!pvNode && tte && ok_to_use_TT(tte, depth, beta, ply))
|
if (!pvNode && tte && ok_to_use_TT(tte, depth, beta, ply, true))
|
||||||
{
|
{
|
||||||
assert(tte->type() != VALUE_TYPE_EVAL);
|
assert(tte->type() != VALUE_TYPE_EVAL);
|
||||||
|
|
||||||
@@ -1666,7 +1667,7 @@ namespace {
|
|||||||
alpha = bestValue;
|
alpha = bestValue;
|
||||||
|
|
||||||
// If we are near beta then try to get a cutoff pushing checks a bit further
|
// If we are near beta then try to get a cutoff pushing checks a bit further
|
||||||
bool deepChecks = depth == -OnePly && staticValue >= beta - PawnValueMidgame / 8;
|
bool deepChecks = (depth == -OnePly && staticValue >= beta - PawnValueMidgame / 8);
|
||||||
|
|
||||||
// Initialize a MovePicker object for the current position, and prepare
|
// Initialize a MovePicker object for the current position, and prepare
|
||||||
// to search the moves. Because the depth is <= 0 here, only captures,
|
// to search the moves. Because the depth is <= 0 here, only captures,
|
||||||
@@ -2306,14 +2307,18 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ok_to_use_TT() returns true if a transposition table score
|
// ok_to_use_TT() returns true if a transposition table score can be used at a
|
||||||
// can be used at a given point in search.
|
// given point in search. To avoid zugzwang issues TT cutoffs at the root node
|
||||||
|
// of a null move verification search are not allowed if the TT value was found
|
||||||
|
// by a null search, this is implemented testing allowNullmove and TT entry type.
|
||||||
|
|
||||||
bool ok_to_use_TT(const TTEntry* tte, Depth depth, Value beta, int ply) {
|
bool ok_to_use_TT(const TTEntry* tte, Depth depth, Value beta, int ply, bool allowNullmove) {
|
||||||
|
|
||||||
Value v = value_from_tt(tte->value(), ply);
|
Value v = value_from_tt(tte->value(), ply);
|
||||||
|
|
||||||
return ( tte->depth() >= depth
|
return (allowNullmove || !(tte->type() & VALUE_TYPE_NULL) || !ZugDetection)
|
||||||
|
|
||||||
|
&& ( tte->depth() >= depth
|
||||||
|| v >= Max(value_mate_in(PLY_MAX), beta)
|
|| v >= Max(value_mate_in(PLY_MAX), beta)
|
||||||
|| v < Min(value_mated_in(PLY_MAX), beta))
|
|| v < Min(value_mated_in(PLY_MAX), beta))
|
||||||
|
|
||||||
|
|||||||
@@ -46,8 +46,8 @@
|
|||||||
/// the 32 bits of the data field are so defined
|
/// the 32 bits of the data field are so defined
|
||||||
///
|
///
|
||||||
/// bit 0-16: move
|
/// bit 0-16: move
|
||||||
/// bit 17-19: not used
|
/// bit 17-18: not used
|
||||||
/// bit 20-22: value type
|
/// bit 19-22: value type
|
||||||
/// bit 23-31: generation
|
/// bit 23-31: generation
|
||||||
|
|
||||||
class TTEntry {
|
class TTEntry {
|
||||||
@@ -55,14 +55,14 @@ class TTEntry {
|
|||||||
public:
|
public:
|
||||||
TTEntry() {}
|
TTEntry() {}
|
||||||
TTEntry(uint32_t k, Value v, ValueType t, Depth d, Move m, int generation)
|
TTEntry(uint32_t k, Value v, ValueType t, Depth d, Move m, int generation)
|
||||||
: key_ (k), data((m & 0x1FFFF) | (t << 20) | (generation << 23)),
|
: key_ (k), data((m & 0x1FFFF) | (t << 19) | (generation << 23)),
|
||||||
value_(int16_t(v)), depth_(int16_t(d)) {}
|
value_(int16_t(v)), depth_(int16_t(d)) {}
|
||||||
|
|
||||||
uint32_t key() const { return key_; }
|
uint32_t key() const { return key_; }
|
||||||
Depth depth() const { return Depth(depth_); }
|
Depth depth() const { return Depth(depth_); }
|
||||||
Move move() const { return Move(data & 0x1FFFF); }
|
Move move() const { return Move(data & 0x1FFFF); }
|
||||||
Value value() const { return Value(value_); }
|
Value value() const { return Value(value_); }
|
||||||
ValueType type() const { return ValueType((data >> 20) & 7); }
|
ValueType type() const { return ValueType((data >> 19) & 0xF); }
|
||||||
int generation() const { return (data >> 23); }
|
int generation() const { return (data >> 23); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -113,6 +113,9 @@ namespace {
|
|||||||
o["UCI_Chess960"] = Option(false);
|
o["UCI_Chess960"] = Option(false);
|
||||||
o["UCI_AnalyseMode"] = Option(false);
|
o["UCI_AnalyseMode"] = Option(false);
|
||||||
|
|
||||||
|
// Temporary hack for 1.7.1 to be removed in next release
|
||||||
|
o["Zugzwang detection"] = Option(false);
|
||||||
|
|
||||||
// Any option should know its name so to be easily printed
|
// Any option should know its name so to be easily printed
|
||||||
for (Options::iterator it = o.begin(); it != o.end(); ++it)
|
for (Options::iterator it = o.begin(); it != o.end(); ++it)
|
||||||
it->second.name = it->first;
|
it->second.name = it->first;
|
||||||
|
|||||||
+7
-4
@@ -33,13 +33,16 @@
|
|||||||
////
|
////
|
||||||
|
|
||||||
enum ValueType {
|
enum ValueType {
|
||||||
VALUE_TYPE_NONE = 0,
|
VALUE_TYPE_NONE = 0,
|
||||||
VALUE_TYPE_UPPER = 1, // Upper bound
|
VALUE_TYPE_UPPER = 1, // Upper bound
|
||||||
VALUE_TYPE_LOWER = 2, // Lower bound
|
VALUE_TYPE_LOWER = 2, // Lower bound
|
||||||
VALUE_TYPE_EXACT = 3, // Exact score
|
VALUE_TYPE_EXACT = 3, // Exact score
|
||||||
VALUE_TYPE_EVAL = 4, // Evaluation cache
|
VALUE_TYPE_EVAL = 4, // Static evaluation value
|
||||||
VALUE_TYPE_EV_UP = 5, // Evaluation cache for upper bound
|
VALUE_TYPE_NULL = 8, // Null search value
|
||||||
VALUE_TYPE_EV_LO = 6 // Evaluation cache for lower bound
|
|
||||||
|
VALUE_TYPE_EV_UP = VALUE_TYPE_EVAL | VALUE_TYPE_UPPER,
|
||||||
|
VALUE_TYPE_EV_LO = VALUE_TYPE_EVAL | VALUE_TYPE_LOWER,
|
||||||
|
VALUE_TYPE_NS_LO = VALUE_TYPE_NULL | VALUE_TYPE_LOWER,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user