diff --git a/modules/juce_core/native/juce_android_SystemStats.cpp b/modules/juce_core/native/juce_android_SystemStats.cpp index 2a5cfee9e9..c37703b271 100644 --- a/modules/juce_core/native/juce_android_SystemStats.cpp +++ b/modules/juce_core/native/juce_android_SystemStats.cpp @@ -282,7 +282,7 @@ String SystemStats::getDisplayLanguage() { return getUserLanguage() + "-" + getU //============================================================================== void CPUInformation::initialise() noexcept { - numCpus = jmax ((int) 1, (int) sysconf (_SC_NPROCESSORS_ONLN)); + numPhysicalCPUs = numLogicalCPUs = jmax ((int) 1, (int) sysconf (_SC_NPROCESSORS_ONLN)); } //============================================================================== diff --git a/modules/juce_core/native/juce_linux_SystemStats.cpp b/modules/juce_core/native/juce_linux_SystemStats.cpp index af8d6e1d91..b4245630ef 100644 --- a/modules/juce_core/native/juce_linux_SystemStats.cpp +++ b/modules/juce_core/native/juce_linux_SystemStats.cpp @@ -153,7 +153,13 @@ void CPUInformation::initialise() noexcept hasAVX = flags.contains ("avx"); hasAVX2 = flags.contains ("avx2"); - numCpus = getCpuInfo ("processor").getIntValue() + 1; + numLogicalCPUs = getCpuInfo ("processor").getIntValue() + 1; + + // Assume CPUs in all sockets have the same number of cores + numPhysicalCPUs = getCpuInfo ("cpu cores").getIntValue() * (getCpuInfo ("physical id").getIntValue() + 1); + + if (numPhysicalCpus <= 0) + numPhysicalCpus = numLogicalCPUs; } //============================================================================== diff --git a/modules/juce_core/native/juce_mac_SystemStats.mm b/modules/juce_core/native/juce_mac_SystemStats.mm index 83dec374e0..cdf1d8d741 100644 --- a/modules/juce_core/native/juce_mac_SystemStats.mm +++ b/modules/juce_core/native/juce_mac_SystemStats.mm @@ -91,7 +91,16 @@ void CPUInformation::initialise() noexcept hasAVX2 = (b & (1u << 5)) != 0; #endif - numCpus = (int) [[NSProcessInfo processInfo] activeProcessorCount]; + numLogicalCPUs = (int) [[NSProcessInfo processInfo] activeProcessorCount]; + + unsigned int physicalcpu = 0; + size_t len = sizeof (physicalcpu); + + if (sysctlbyname ("hw.physicalcpu", &physicalcpu, &len, nullptr, 0) >= 0) + numPhysicalCPUs = (int) physicalcpu; + + if (numPhysicalCPUs <= 0) + numPhysicalCPUs = numLogicalCPUs; } //============================================================================== diff --git a/modules/juce_core/native/juce_win32_SystemStats.cpp b/modules/juce_core/native/juce_win32_SystemStats.cpp index c8328e2685..e7ad563f62 100644 --- a/modules/juce_core/native/juce_win32_SystemStats.cpp +++ b/modules/juce_core/native/juce_win32_SystemStats.cpp @@ -103,6 +103,25 @@ String SystemStats::getCpuModel() return String (name).trim(); } +static int findNumberOfPhysicalCores() noexcept +{ + int numPhysicalCores = 0; + DWORD bufferSize = 0; + + if (GetLogicalProcessorInformation (nullptr, &bufferSize)) + { + const size_t numBuffers = (size_t) (bufferSize / sizeof (SYSTEM_LOGICAL_PROCESSOR_INFORMATION)); + HeapBlock buffer (numBuffers); + + if (GetLogicalProcessorInformation (buffer, &bufferSize)) + for (size_t i = 0; i < numBuffers; ++i) + if (buffer[i].Relationship == RelationProcessorCore) + ++numPhysicalCores; + } + + return numPhysicalCores; +} + //============================================================================== void CPUInformation::initialise() noexcept { @@ -126,7 +145,11 @@ void CPUInformation::initialise() noexcept SYSTEM_INFO systemInfo; GetNativeSystemInfo (&systemInfo); - numCpus = (int) systemInfo.dwNumberOfProcessors; + numLogicalCPUs = (int) systemInfo.dwNumberOfProcessors; + numPhysicalCPUs = findNumberOfPhysicalCores(); + + if (numPhysicalCPUs <= 0) + numPhysicalCPUs = numLogicalCPUs; } #if JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS diff --git a/modules/juce_core/system/juce_SystemStats.cpp b/modules/juce_core/system/juce_SystemStats.cpp index cd43dcb0e4..1dc8bde385 100644 --- a/modules/juce_core/system/juce_SystemStats.cpp +++ b/modules/juce_core/system/juce_SystemStats.cpp @@ -67,19 +67,15 @@ String SystemStats::getJUCEVersion() //============================================================================== struct CPUInformation { - CPUInformation() noexcept - : numCpus (0), hasMMX (false), hasSSE (false), - hasSSE2 (false), hasSSE3 (false), has3DNow (false), - hasSSSE3 (false), hasSSE41 (false), hasSSE42 (false), - hasAVX (false), hasAVX2 (false) - { - initialise(); - } + CPUInformation() noexcept { initialise(); } void initialise() noexcept; - int numCpus; - bool hasMMX, hasSSE, hasSSE2, hasSSE3, has3DNow, hasSSSE3, hasSSE41, hasSSE42, hasAVX, hasAVX2; + int numLogicalCPUs = 0, numPhysicalCPUs = 0; + + bool hasMMX = false, hasSSE = false, hasSSE2 = false, hasSSE3 = false, + has3DNow = false, hasSSSE3 = false, hasSSE41 = false, + hasSSE42 = false, hasAVX = false, hasAVX2 = false; }; static const CPUInformation& getCPUInformation() noexcept @@ -88,17 +84,18 @@ static const CPUInformation& getCPUInformation() noexcept return info; } -int SystemStats::getNumCpus() noexcept { return getCPUInformation().numCpus; } -bool SystemStats::hasMMX() noexcept { return getCPUInformation().hasMMX; } -bool SystemStats::has3DNow() noexcept { return getCPUInformation().has3DNow; } -bool SystemStats::hasSSE() noexcept { return getCPUInformation().hasSSE; } -bool SystemStats::hasSSE2() noexcept { return getCPUInformation().hasSSE2; } -bool SystemStats::hasSSE3() noexcept { return getCPUInformation().hasSSE3; } -bool SystemStats::hasSSSE3() noexcept { return getCPUInformation().hasSSSE3; } -bool SystemStats::hasSSE41() noexcept { return getCPUInformation().hasSSE41; } -bool SystemStats::hasSSE42() noexcept { return getCPUInformation().hasSSE42; } -bool SystemStats::hasAVX() noexcept { return getCPUInformation().hasAVX; } -bool SystemStats::hasAVX2() noexcept { return getCPUInformation().hasAVX2; } +int SystemStats::getNumCpus() noexcept { return getCPUInformation().numLogicalCPUs; } +int SystemStats::getNumPhysicalCpus() noexcept { return getCPUInformation().numPhysicalCPUs; } +bool SystemStats::hasMMX() noexcept { return getCPUInformation().hasMMX; } +bool SystemStats::has3DNow() noexcept { return getCPUInformation().has3DNow; } +bool SystemStats::hasSSE() noexcept { return getCPUInformation().hasSSE; } +bool SystemStats::hasSSE2() noexcept { return getCPUInformation().hasSSE2; } +bool SystemStats::hasSSE3() noexcept { return getCPUInformation().hasSSE3; } +bool SystemStats::hasSSSE3() noexcept { return getCPUInformation().hasSSSE3; } +bool SystemStats::hasSSE41() noexcept { return getCPUInformation().hasSSE41; } +bool SystemStats::hasSSE42() noexcept { return getCPUInformation().hasSSE42; } +bool SystemStats::hasAVX() noexcept { return getCPUInformation().hasAVX; } +bool SystemStats::hasAVX2() noexcept { return getCPUInformation().hasAVX2; } //============================================================================== diff --git a/modules/juce_core/system/juce_SystemStats.h b/modules/juce_core/system/juce_SystemStats.h index b4b99c63d1..6f29412b0d 100644 --- a/modules/juce_core/system/juce_SystemStats.h +++ b/modules/juce_core/system/juce_SystemStats.h @@ -140,9 +140,12 @@ public: //============================================================================== // CPU and memory information.. - /** Returns the number of CPU cores. */ + /** Returns the number of logical CPU cores. */ static int getNumCpus() noexcept; + /** Returns the number of physical CPU cores. */ + static int getNumPhysicalCpus() noexcept; + /** Returns the approximate CPU speed. @returns the speed in megahertz, e.g. 1500, 2500, 32000 (depending on what year you're reading this...)