#endif
+#if !defined(NO_PREFETCH)
+# include <xmmintrin.h>
+#endif
+
#include <cassert>
#include <cstdio>
-#include <cstring>
#include <iomanip>
#include <iostream>
#include <sstream>
#include "bitcount.h"
#include "misc.h"
+#include "thread.h"
using namespace std;
/// Version number. If this is left empty, the current date (in the format
/// YYMMDD) is used as a version number.
-static const string EngineVersion = "1.7";
+static const string EngineVersion = "";
static const string AppName = "Stockfish";
static const string AppTag = "";
//// Variables
////
-bool Chess960;
-
uint64_t dbg_cnt0 = 0;
uint64_t dbg_cnt1 = 0;
const string engine_name() {
- const string cpu64(CpuHas64BitPath ? " 64bit" : "");
+ const string cpu64(CpuIs64Bit ? " 64bit" : "");
if (!EngineVersion.empty())
- return AppName+ " " + EngineVersion + cpu64;
+ return AppName + " " + EngineVersion + cpu64;
string date(__DATE__); // From compiler, format is "Sep 21 2008"
string months("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec");
}
-/// builtin_cpu_count() tries to detect the number of CPU cores, if
-/// hyper-threading is enabled this is the number of logical processors.
+/// cpu_count() tries to detect the number of CPU cores.
#if !defined(_MSC_VER)
# if defined(_SC_NPROCESSORS_ONLN)
-static int builtin_cpu_count() {
- return Min(sysconf(_SC_NPROCESSORS_ONLN), 8);
+int cpu_count() {
+ return Min(sysconf(_SC_NPROCESSORS_ONLN), MAX_THREADS);
}
# elif defined(__hpux)
-static int builtin_cpu_count() {
+int cpu_count() {
struct pst_dynamic psd;
if (pstat_getdynamic(&psd, sizeof(psd), (size_t)1, 0) == -1)
return 1;
- return Min(psd.psd_proc_cnt, 8);
+ return Min(psd.psd_proc_cnt, MAX_THREADS);
}
# else
-static int builtin_cpu_count() {
+int cpu_count() {
return 1;
}
# endif
#else
-static int builtin_cpu_count() {
+int cpu_count() {
SYSTEM_INFO s;
GetSystemInfo(&s);
- return Min(s.dwNumberOfProcessors, 8);
+ return Min(s.dwNumberOfProcessors, MAX_THREADS);
}
#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;
+/// Check for console input. Original code from Beowulf and Olithink
- 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
-*/
#ifndef _WIN32
-/* Non-windows version */
-int Bioskey()
+
+int data_available()
{
- fd_set readfds;
+ fd_set readfds;
struct timeval timeout;
FD_ZERO(&readfds);
FD_SET(fileno(stdin), &readfds);
- /* Set to timeout immediately */
- timeout.tv_sec = 0;
+ timeout.tv_sec = 0; // Set to timeout immediately
timeout.tv_usec = 0;
select(16, &readfds, 0, 0, &timeout);
}
#else
-/* Windows-version */
-#include <windows.h>
-#include <conio.h>
-int Bioskey()
+
+int data_available()
{
- static int init = 0,
- pipe;
- static HANDLE inh;
- DWORD dw;
- /* If we're running under XBoard then we can't use _kbhit() as the input
- * commands are sent to us directly over the internal pipe */
-
-#if defined(FILE_CNT)
- if (stdin->_cnt > 0)
- return stdin->_cnt;
-#endif
- if (!init) {
- init = 1;
+ static HANDLE inh = NULL;
+ static bool usePipe;
+ INPUT_RECORD rec[256];
+ DWORD dw, recCnt;
+
+ if (!inh)
+ {
inh = GetStdHandle(STD_INPUT_HANDLE);
- pipe = !GetConsoleMode(inh, &dw);
- if (!pipe) {
+ usePipe = !GetConsoleMode(inh, &dw);
+ if (!usePipe)
+ {
SetConsoleMode(inh, dw & ~(ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT));
FlushConsoleInputBuffer(inh);
}
}
- if (pipe) {
- if (!PeekNamedPipe(inh, NULL, 0, NULL, &dw, NULL))
- return 1;
- return dw;
- } else {
- // Count the number of unread input records, including keyboard,
- // mouse, and window-resizing input records.
- GetNumberOfConsoleInputEvents(inh, &dw);
- if (dw <= 0)
- return 0;
-
- // Read data from console without removing it from the buffer
- INPUT_RECORD rec[256];
- DWORD recCnt;
- if (!PeekConsoleInput(inh, rec, Min(dw, 256), &recCnt))
- return 0;
-
- // Search for at least one keyboard event
- for (DWORD i = 0; i < recCnt; i++)
- if (rec[i].EventType == KEY_EVENT)
- return 1;
+ // If we're running under XBoard then we can't use PeekConsoleInput() as
+ // the input commands are sent to us directly over the internal pipe.
+ if (usePipe)
+ return PeekNamedPipe(inh, NULL, 0, NULL, &dw, NULL) ? dw : 1;
+
+ // Count the number of unread input records, including keyboard,
+ // mouse, and window-resizing input records.
+ GetNumberOfConsoleInputEvents(inh, &dw);
+
+ // Read data from console without removing it from the buffer
+ if (dw <= 0 || !PeekConsoleInput(inh, rec, Min(dw, 256), &recCnt))
return 0;
- }
+
+ // Search for at least one keyboard event
+ for (DWORD i = 0; i < recCnt; i++)
+ if (rec[i].EventType == KEY_EVENT)
+ return 1;
+
+ return 0;
}
+
+#endif
+
+
+/// prefetch() preloads the given address in L1/L2 cache. This is a non
+/// blocking function and do not stalls the CPU waiting for data to be
+/// loaded from RAM, that can be very slow.
+#if defined(NO_PREFETCH)
+void prefetch(char*) {}
+#else
+
+void prefetch(char* addr) {
+
+#if defined(__INTEL_COMPILER) || defined(__ICL)
+ // This hack prevents prefetches to be optimized away by
+ // Intel compiler. Both MSVC and gcc seems not affected.
+ __asm__ ("");
+#endif
+
+ _mm_prefetch(addr, _MM_HINT_T2);
+ _mm_prefetch(addr+64, _MM_HINT_T2); // 64 bytes ahead
+}
+
#endif
+