int main(int argc, char* argv[]) {
- // Don't sync with C library I/O buffers, faster but now using printf()
- // or scanf() could yield to issues because buffers are independent.
- cout.sync_with_stdio(false);
- cin.sync_with_stdio(false);
-
cout << engine_info() << endl;
bitboards_init();
# include <xmmintrin.h>
#endif
-#include <algorithm>
#include <iomanip>
#include <iostream>
#include <sstream>
#if defined(_WIN32) || defined(_WIN64)
SYSTEM_INFO s;
GetSystemInfo(&s);
- return std::min(int(s.dwNumberOfProcessors), MAX_THREADS);
+ return s.dwNumberOfProcessors;
#else
# if defined(_SC_NPROCESSORS_ONLN)
- return std::min((int)sysconf(_SC_NPROCESSORS_ONLN), MAX_THREADS);
+ return sysconf(_SC_NPROCESSORS_ONLN);
# elif defined(__hpux)
struct pst_dynamic psd;
if (pstat_getdynamic(&psd, sizeof(psd), (size_t)1, 0) == -1)
return 1;
- return std::min((int)psd.psd_proc_cnt, MAX_THREADS);
+ return psd.psd_proc_cnt;
# else
return 1;
# endif
#include <fstream>
#include <string>
-#include "lock.h"
#include "types.h"
extern const std::string engine_info(bool to_uci = false);
extern int cpu_count();
extern void timed_wait(WaitCondition&, Lock&, int);
extern void prefetch(char* addr);
+extern void start_logger(bool b);
extern void dbg_hit_on(bool b);
extern void dbg_hit_on_c(bool c, bool b);
sys_time_t t;
};
-extern void start_logger(bool b);
-
#endif // !defined(MISC_H_INCLUDED)
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#if !defined(LOCK_H_INCLUDED)
-#define LOCK_H_INCLUDED
+#if !defined(PLATFORM_H_INCLUDED)
+#define PLATFORM_H_INCLUDED
-#if !defined(_WIN32) && !defined(_WIN64)
+#if defined(_MSC_VER)
-# include <pthread.h>
+// Disable some silly and noisy warning from MSVC compiler
+#pragma warning(disable: 4127) // Conditional expression is constant
+#pragma warning(disable: 4146) // Unary minus operator applied to unsigned type
+#pragma warning(disable: 4800) // Forcing value to bool 'true' or 'false'
+#pragma warning(disable: 4996) // Function _ftime() may be unsafe
+
+// MSVC does not support <inttypes.h>
+typedef signed __int8 int8_t;
+typedef unsigned __int8 uint8_t;
+typedef signed __int16 int16_t;
+typedef unsigned __int16 uint16_t;
+typedef signed __int32 int32_t;
+typedef unsigned __int32 uint32_t;
+typedef signed __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+
+#else
+# include <inttypes.h>
+#endif
+
+#if !defined(_WIN32) && !defined(_WIN64) // Linux - Unix
+# include <sys/time.h>
+typedef timeval sys_time_t;
+
+inline void system_time(sys_time_t* t) { gettimeofday(t, NULL); }
+inline uint64_t time_to_msec(const sys_time_t& t) { return t.tv_sec * 1000LL + t.tv_usec / 1000; }
+
+# include <pthread.h>
typedef pthread_mutex_t Lock;
typedef pthread_cond_t WaitCondition;
typedef pthread_t ThreadHandle;
+typedef void*(*start_fn)(void*);
# define lock_init(x) pthread_mutex_init(&(x), NULL)
# define lock_grab(x) pthread_mutex_lock(&(x))
# define cond_signal(x) pthread_cond_signal(&(x))
# define cond_wait(x,y) pthread_cond_wait(&(x),&(y))
# define cond_timedwait(x,y,z) pthread_cond_timedwait(&(x),&(y),z)
-# define thread_create(x,f,id) !pthread_create(&(x),NULL,f,&(id))
+# define thread_create(x,f,id) !pthread_create(&(x),NULL,(start_fn)f,&(id))
# define thread_join(x) pthread_join(x, NULL)
-#else
+#else // Windows and MinGW
+
+# include <sys/timeb.h>
+typedef _timeb sys_time_t;
+
+inline void system_time(sys_time_t* t) { _ftime(t); }
+inline uint64_t time_to_msec(const sys_time_t& t) { return t.time * 1000LL + t.millitm; }
#if !defined(NOMINMAX)
# define NOMINMAX // disable macros min() and max()
# define cond_signal(x) SetEvent(x)
# define cond_wait(x,y) { lock_release(y); WaitForSingleObject(x, INFINITE); lock_grab(y); }
# define cond_timedwait(x,y,z) { lock_release(y); WaitForSingleObject(x,z); lock_grab(y); }
-# define thread_create(x,f,id) (x = CreateThread(NULL,0,f,&(id),0,NULL), x != NULL)
+# define thread_create(x,f,id) (x = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)f,&(id),0,NULL), x != NULL)
# define thread_join(x) { WaitForSingleObject(x, INFINITE); CloseHandle(x); }
#endif
-#endif // !defined(LOCK_H_INCLUDED)
+#endif // !defined(PLATFORM_H_INCLUDED)
bool connected_moves(const Position& pos, Move m1, Move m2);
Value value_to_tt(Value v, int ply);
Value value_from_tt(Value v, int ply);
- bool can_return_tt(const TTEntry* tte, Depth depth, Value beta, int ply);
+ bool can_return_tt(const TTEntry* tte, Depth depth, Value ttValue, Value beta);
bool connected_threat(const Position& pos, Move m, Move threat);
- Value refine_eval(const TTEntry* tte, Value defaultEval, int ply);
+ Value refine_eval(const TTEntry* tte, Value ttValue, Value defaultEval);
Move do_skill_level();
string score_to_uci(Value v, Value alpha = -VALUE_INFINITE, Value beta = VALUE_INFINITE);
void pv_info_to_log(Position& pos, int depth, Value score, int time, Move pv[]);
Move ttMove, move, excludedMove, bestMove, threatMove;
Depth ext, newDepth;
Bound bt;
- Value bestValue, value, oldAlpha;
+ Value bestValue, value, oldAlpha, ttValue;
Value refinedValue, nullValue, futilityBase, futilityValue;
bool isPvMove, inCheck, singularExtensionNode, givesCheck;
bool captureOrPromotion, dangerous, doFullDepthSearch;
{
tte = NULL;
ttMove = excludedMove = MOVE_NONE;
+ ttValue = VALUE_ZERO;
sp = ss->sp;
bestMove = sp->bestMove;
threatMove = sp->threatMove;
posKey = excludedMove ? pos.exclusion_key() : pos.key();
tte = TT.probe(posKey);
ttMove = RootNode ? RootMoves[PVIdx].pv[0] : tte ? tte->move() : MOVE_NONE;
+ ttValue = tte ? value_from_tt(tte->value(), ss->ply) : VALUE_ZERO;
// At PV nodes we check for exact scores, while at non-PV nodes we check for
// a fail high/low. Biggest advantage at probing at PV nodes is to have a
// smooth experience in analysis mode. We don't probe at Root nodes otherwise
// we should also update RootMoveList to avoid bogus output.
if (!RootNode && tte && (PvNode ? tte->depth() >= depth && tte->type() == BOUND_EXACT
- : can_return_tt(tte, depth, beta, ss->ply)))
+ : can_return_tt(tte, depth, ttValue, beta)))
{
TT.refresh(tte);
ss->currentMove = ttMove; // Can be MOVE_NONE
- value = value_from_tt(tte->value(), ss->ply);
- if ( value >= beta
+ if ( ttValue >= beta
&& ttMove
&& !pos.is_capture_or_promotion(ttMove)
&& ttMove != ss->killers[0])
ss->killers[1] = ss->killers[0];
ss->killers[0] = ttMove;
}
- return value;
+ return ttValue;
}
// Step 5. Evaluate the position statically and update parent's gain statistics
ss->eval = tte->static_value();
ss->evalMargin = tte->static_value_margin();
- refinedValue = refine_eval(tte, ss->eval, ss->ply);
+ refinedValue = refine_eval(tte, ttValue, ss->eval);
}
else
{
&& move == ttMove
&& pos.pl_move_is_legal(move, ci.pinned))
{
- Value ttValue = value_from_tt(tte->value(), ss->ply);
-
if (abs(ttValue) < VALUE_KNOWN_WIN)
{
Value rBeta = ttValue - int(depth);
StateInfo st;
Move ttMove, move, bestMove;
- Value bestValue, value, evalMargin, futilityValue, futilityBase;
+ Value ttValue, bestValue, value, evalMargin, futilityValue, futilityBase;
bool inCheck, enoughMaterial, givesCheck, evasionPrunable;
const TTEntry* tte;
Depth ttDepth;
// pruning, but only for move ordering.
tte = TT.probe(pos.key());
ttMove = (tte ? tte->move() : MOVE_NONE);
+ ttValue = tte ? value_from_tt(tte->value(),ss->ply) : VALUE_ZERO;
- if (!PvNode && tte && can_return_tt(tte, ttDepth, beta, ss->ply))
+ if (!PvNode && tte && can_return_tt(tte, ttDepth, ttValue, beta))
{
ss->currentMove = ttMove; // Can be MOVE_NONE
- return value_from_tt(tte->value(), ss->ply);
+ return ttValue;
}
// Evaluate the position statically
// can_return_tt() returns true if a transposition table score can be used to
// cut-off at a given point in search.
- bool can_return_tt(const TTEntry* tte, Depth depth, Value beta, int ply) {
-
- Value v = value_from_tt(tte->value(), ply);
+ bool can_return_tt(const TTEntry* tte, Depth depth, Value v, Value beta) {
return ( tte->depth() >= depth
|| v >= std::max(VALUE_MATE_IN_MAX_PLY, beta)
// refine_eval() returns the transposition table score if possible, otherwise
// falls back on static position evaluation.
- Value refine_eval(const TTEntry* tte, Value defaultEval, int ply) {
+ Value refine_eval(const TTEntry* tte, Value v, Value defaultEval) {
assert(tte);
- Value v = value_from_tt(tte->value(), ply);
-
if ( ((tte->type() & BOUND_LOWER) && v >= defaultEval)
|| ((tte->type() & BOUND_UPPER) && v < defaultEval))
return v;
// and last thread are special. First one is the main search thread while the
// last one mimics a timer, they run in main_loop() and timer_loop().
-#if defined(_WIN32) || defined(_WIN64)
- DWORD WINAPI start_routine(LPVOID thread) {
-#else
- void* start_routine(void* thread) {
-#endif
-
- Thread* th = (Thread*)thread;
+ long start_routine(Thread* th) {
if (th->threadID == 0)
th->main_loop();
cond_init(sleepCond);
lock_init(splitLock);
- for (int i = 0; i <= MAX_THREADS; i++)
- {
- lock_init(threads[i].sleepLock);
- cond_init(threads[i].sleepCond);
-
- for (int j = 0; j < MAX_SPLITPOINTS_PER_THREAD; j++)
- lock_init(threads[i].splitPoints[j].lock);
- }
-
// Allocate main thread tables to call evaluate() also when not searching
threads[0].pawnTable.init();
threads[0].materialTable.init();
threads[i].do_sleep = (i != 0); // Avoid a race with start_thinking()
threads[i].threadID = i;
+ lock_init(threads[i].sleepLock);
+ cond_init(threads[i].sleepCond);
+
+ for (int j = 0; j < MAX_SPLITPOINTS_PER_THREAD; j++)
+ lock_init(threads[i].splitPoints[j].lock);
+
if (!thread_create(threads[i].handle, start_routine, threads[i]))
{
std::cerr << "Failed to create thread number " << i << std::endl;
template <bool Fake>
Value ThreadsManager::split(Position& pos, Stack* ss, Value alpha, Value beta,
Value bestValue, Move* bestMove, Depth depth,
- Move threatMove, int moveCount, MovePicker *mp, int nodeType) {
+ Move threatMove, int moveCount, MovePicker* mp, int nodeType) {
assert(pos.pos_is_ok());
assert(bestValue > -VALUE_INFINITE);
assert(bestValue <= alpha);
#include <set>
-#include "lock.h"
#include "material.h"
#include "movepick.h"
#include "pawns.h"
#include <climits>
#include <cstdlib>
-#if defined(_MSC_VER)
-
-// Disable some silly and noisy warning from MSVC compiler
-#pragma warning(disable: 4127) // Conditional expression is constant
-#pragma warning(disable: 4146) // Unary minus operator applied to unsigned type
-#pragma warning(disable: 4800) // Forcing value to bool 'true' or 'false'
-#pragma warning(disable: 4996) // Function _ftime() may be unsafe
-
-// MSVC does not support <inttypes.h>
-typedef signed __int8 int8_t;
-typedef unsigned __int8 uint8_t;
-typedef signed __int16 int16_t;
-typedef unsigned __int16 uint16_t;
-typedef signed __int32 int32_t;
-typedef unsigned __int32 uint32_t;
-typedef signed __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-
-#else
-# include <inttypes.h>
-#endif
-
-#if defined(_WIN32) || defined(_WIN64)
-# include <sys/timeb.h>
-typedef _timeb sys_time_t;
-
-inline void system_time(sys_time_t* t) { _ftime(t); }
-inline uint64_t time_to_msec(const sys_time_t& t) { return t.time * 1000LL + t.millitm; }
-#else
-# include <sys/time.h>
-typedef timeval sys_time_t;
-
-inline void system_time(sys_time_t* t) { gettimeofday(t, NULL); }
-inline uint64_t time_to_msec(const sys_time_t& t) { return t.tv_sec * 1000LL + t.tv_usec / 1000; }
-#endif
+#include "platform.h"
#if defined(_WIN64)
# include <intrin.h> // MSVC popcnt and bsfq instrinsics