|
|
@@ -38,6 +38,7 @@
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
#include <float.h>
|
|
|
+#include <intrin.h>
|
|
|
#else
|
|
|
// From http://stereopsis.com/FPU.html
|
|
|
|
|
|
@@ -64,6 +65,14 @@ inline void SetFPUState(unsigned control)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+void CpuID(int i, int regs[4]) {
|
|
|
+ #ifdef _MSC_VER
|
|
|
+ __cpuid(regs, i);
|
|
|
+ #else
|
|
|
+ __asm__ __volatile__ ("cpuid" : "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3]) : "a" (i), "c" (0));
|
|
|
+ #endif
|
|
|
+}
|
|
|
+
|
|
|
#include "DebugNew.h"
|
|
|
|
|
|
#ifdef WIN32
|
|
|
@@ -252,39 +261,42 @@ String GetConsoleInput()
|
|
|
|
|
|
unsigned GetNumCPUCores()
|
|
|
{
|
|
|
- #ifdef WIN32
|
|
|
- SYSTEM_INFO info;
|
|
|
- GetSystemInfo(&info);
|
|
|
- unsigned numCores = info.dwNumberOfProcessors;
|
|
|
- #else
|
|
|
- unsigned numCores = sysconf(_SC_NPROCESSORS_ONLN);
|
|
|
- #endif
|
|
|
+ // Get number of CPU cores without counting hyperthreaded cores, as creating a worker thread for each threaded core results
|
|
|
+ // in extra time spent synchronizing. Code based on
|
|
|
+ // http://stackoverflow.com/questions/2901694/programatically-detect-number-of-physical-processors-cores-or-if-hyper-threading
|
|
|
+ int regs[4];
|
|
|
|
|
|
- // If CPU uses hyperthreading, report only half of the cores, as using the "extra" cores for worker threads
|
|
|
- // seems to result in extra time spent synchronizing
|
|
|
- unsigned func = 1;
|
|
|
- unsigned a, b, c, d;
|
|
|
+ // Get vendor
|
|
|
+ char vendor[12];
|
|
|
+ CpuID(0, regs);
|
|
|
+ ((unsigned*)vendor)[0] = regs[1]; // EBX
|
|
|
+ ((unsigned*)vendor)[1] = regs[3]; // EDX
|
|
|
+ ((unsigned*)vendor)[2] = regs[2]; // ECX
|
|
|
+ String cpuVendor = String(vendor, 12);
|
|
|
|
|
|
- // CPUID inline assembly from http://softpixel.com/~cwright/programming/simd/cpuid.php
|
|
|
- #ifdef _MSC_VER
|
|
|
- __asm
|
|
|
+ // Get CPU features
|
|
|
+ CpuID(1, regs);
|
|
|
+ unsigned cpuFeatures = regs[3]; // EDX
|
|
|
+
|
|
|
+ // Logical core count per CPU
|
|
|
+ CpuID(1, regs);
|
|
|
+ unsigned logical = (regs[1] >> 16) & 0xff; // EBX[23:16]
|
|
|
+ unsigned cores = logical;
|
|
|
+
|
|
|
+ if (cpuVendor == "GenuineIntel")
|
|
|
{
|
|
|
- mov eax, func
|
|
|
- cpuid
|
|
|
- mov a, eax
|
|
|
- mov b, ebx
|
|
|
- mov c, ecx
|
|
|
- mov d, edx
|
|
|
+ // Get DCP cache info
|
|
|
+ CpuID(4, regs);
|
|
|
+ cores = ((regs[0] >> 26) & 0x3f) + 1; // EAX[31:26] + 1
|
|
|
+ }
|
|
|
+ else if (cpuVendor == "AuthenticAMD")
|
|
|
+ {
|
|
|
+ // Get NC: Number of CPU cores - 1
|
|
|
+ CpuID(0x80000008, regs);
|
|
|
+ cores = ((unsigned)(regs[2] & 0xff)) + 1; // ECX[7:0] + 1
|
|
|
}
|
|
|
- #else
|
|
|
- __asm__ __volatile__ ("cpuid":
|
|
|
- "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (func));
|
|
|
- #endif
|
|
|
-
|
|
|
- if (d & 0x10000000)
|
|
|
- numCores >>= 1;
|
|
|
|
|
|
- return numCores;
|
|
|
+ return cores;
|
|
|
}
|
|
|
|
|
|
Mutex& GetStaticMutex()
|