From bedff619838dd65c617d043c91cdf5bad4fe605d Mon Sep 17 00:00:00 2001 From: Tom Poole Date: Thu, 4 Oct 2018 09:39:45 +0100 Subject: [PATCH] Added detection for some AVX512 features --- examples/Utilities/SystemInfoDemo.h | 40 ++++++++++++------- .../native/juce_linux_SystemStats.cpp | 30 +++++++++----- .../juce_core/native/juce_mac_SystemStats.mm | 12 +++++- .../native/juce_win32_SystemStats.cpp | 12 +++++- modules/juce_core/system/juce_SystemStats.cpp | 21 ++++++++-- modules/juce_core/system/juce_SystemStats.h | 32 ++++++++++----- 6 files changed, 106 insertions(+), 41 deletions(-) diff --git a/examples/Utilities/SystemInfoDemo.h b/examples/Utilities/SystemInfoDemo.h index 3c2338efb2..82307b08f8 100644 --- a/examples/Utilities/SystemInfoDemo.h +++ b/examples/Utilities/SystemInfoDemo.h @@ -144,21 +144,31 @@ static String getAllSystemInfo() systemInfo << "Number of logical CPUs: " << SystemStats::getNumCpus() << newLine << "Number of physical CPUs: " << SystemStats::getNumPhysicalCpus() << newLine - << "Memory size: " << SystemStats::getMemorySizeInMegabytes() << " MB" << newLine - << "CPU vendor: " << SystemStats::getCpuVendor() << newLine - << "CPU model: " << SystemStats::getCpuModel() << newLine - << "CPU speed: " << SystemStats::getCpuSpeedInMegahertz() << " MHz" << newLine - << "CPU has MMX: " << (SystemStats::hasMMX() ? "yes" : "no") << newLine - << "CPU has SSE: " << (SystemStats::hasSSE() ? "yes" : "no") << newLine - << "CPU has SSE2: " << (SystemStats::hasSSE2() ? "yes" : "no") << newLine - << "CPU has SSE3: " << (SystemStats::hasSSE3() ? "yes" : "no") << newLine - << "CPU has SSSE3: " << (SystemStats::hasSSSE3() ? "yes" : "no") << newLine - << "CPU has SSE4.1: " << (SystemStats::hasSSE41() ? "yes" : "no") << newLine - << "CPU has SSE4.2: " << (SystemStats::hasSSE42() ? "yes" : "no") << newLine - << "CPU has 3DNOW: " << (SystemStats::has3DNow() ? "yes" : "no") << newLine - << "CPU has AVX: " << (SystemStats::hasAVX() ? "yes" : "no") << newLine - << "CPU has AVX2: " << (SystemStats::hasAVX2() ? "yes" : "no") << newLine - << "CPU has Neon: " << (SystemStats::hasNeon() ? "yes" : "no") << newLine + << "Memory size: " << SystemStats::getMemorySizeInMegabytes() << " MB" << newLine + << "CPU vendor: " << SystemStats::getCpuVendor() << newLine + << "CPU model: " << SystemStats::getCpuModel() << newLine + << "CPU speed: " << SystemStats::getCpuSpeedInMegahertz() << " MHz" << newLine + << "CPU has MMX: " << (SystemStats::hasMMX() ? "yes" : "no") << newLine + << "CPU has SSE: " << (SystemStats::hasSSE() ? "yes" : "no") << newLine + << "CPU has SSE2: " << (SystemStats::hasSSE2() ? "yes" : "no") << newLine + << "CPU has SSE3: " << (SystemStats::hasSSE3() ? "yes" : "no") << newLine + << "CPU has SSSE3: " << (SystemStats::hasSSSE3() ? "yes" : "no") << newLine + << "CPU has SSE4.1: " << (SystemStats::hasSSE41() ? "yes" : "no") << newLine + << "CPU has SSE4.2: " << (SystemStats::hasSSE42() ? "yes" : "no") << newLine + << "CPU has 3DNOW: " << (SystemStats::has3DNow() ? "yes" : "no") << newLine + << "CPU has AVX: " << (SystemStats::hasAVX() ? "yes" : "no") << newLine + << "CPU has AVX2: " << (SystemStats::hasAVX2() ? "yes" : "no") << newLine + << "CPU has AVX512F: " << (SystemStats::hasAVX512F() ? "yes" : "no") << newLine + << "CPU has AVX512BW: " << (SystemStats::hasAVX512BW() ? "yes" : "no") << newLine + << "CPU has AVX512CD: " << (SystemStats::hasAVX512CD() ? "yes" : "no") << newLine + << "CPU has AVX512DQ: " << (SystemStats::hasAVX512DQ() ? "yes" : "no") << newLine + << "CPU has AVX512ER: " << (SystemStats::hasAVX512ER() ? "yes" : "no") << newLine + << "CPU has AVX512IFMA: " << (SystemStats::hasAVX512IFMA() ? "yes" : "no") << newLine + << "CPU has AVX512PF: " << (SystemStats::hasAVX512PF() ? "yes" : "no") << newLine + << "CPU has AVX512VBMI: " << (SystemStats::hasAVX512VBMI() ? "yes" : "no") << newLine + << "CPU has AVX512VL: " << (SystemStats::hasAVX512VL() ? "yes" : "no") << newLine + << "CPU has AVX512VPOPCNTDQ: " << (SystemStats::hasAVX512VPOPCNTDQ() ? "yes" : "no") << newLine + << "CPU has Neon: " << (SystemStats::hasNeon() ? "yes" : "no") << newLine << newLine; systemInfo diff --git a/modules/juce_core/native/juce_linux_SystemStats.cpp b/modules/juce_core/native/juce_linux_SystemStats.cpp index 154f01c5ca..01a342841b 100644 --- a/modules/juce_core/native/juce_linux_SystemStats.cpp +++ b/modules/juce_core/native/juce_linux_SystemStats.cpp @@ -142,16 +142,26 @@ String SystemStats::getDisplayLanguage() { return getUserLanguage() + "-" + getU void CPUInformation::initialise() noexcept { auto flags = getCpuInfo ("flags"); - hasMMX = flags.contains ("mmx"); - hasSSE = flags.contains ("sse"); - hasSSE2 = flags.contains ("sse2"); - hasSSE3 = flags.contains ("sse3"); - has3DNow = flags.contains ("3dnow"); - hasSSSE3 = flags.contains ("ssse3"); - hasSSE41 = flags.contains ("sse4_1"); - hasSSE42 = flags.contains ("sse4_2"); - hasAVX = flags.contains ("avx"); - hasAVX2 = flags.contains ("avx2"); + hasMMX = flags.contains ("mmx"); + hasSSE = flags.contains ("sse"); + hasSSE2 = flags.contains ("sse2"); + hasSSE3 = flags.contains ("sse3"); + has3DNow = flags.contains ("3dnow"); + hasSSSE3 = flags.contains ("ssse3"); + hasSSE41 = flags.contains ("sse4_1"); + hasSSE42 = flags.contains ("sse4_2"); + hasAVX = flags.contains ("avx"); + hasAVX2 = flags.contains ("avx2"); + hasAVX512F = flags.contains ("avx512f"); + hasAVX512BW = flags.contains ("avx512bw"); + hasAVX512CD = flags.contains ("avx512cd"); + hasAVX512DQ = flags.contains ("avx512dq"); + hasAVX512ER = flags.contains ("avx512er"); + hasAVX512IFMA = flags.contains ("avx512ifma"); + hasAVX512PF = flags.contains ("avx512pf"); + hasAVX512VBMI = flags.contains ("avx512vbmi"); + hasAVX512VL = flags.contains ("avx512vl"); + hasAVX512VPOPCNTDQ = flags.contains ("avx512_vpopcntdq"); numLogicalCPUs = getCpuInfo ("processor").getIntValue() + 1; diff --git a/modules/juce_core/native/juce_mac_SystemStats.mm b/modules/juce_core/native/juce_mac_SystemStats.mm index 0df5df2429..549c48b223 100644 --- a/modules/juce_core/native/juce_mac_SystemStats.mm +++ b/modules/juce_core/native/juce_mac_SystemStats.mm @@ -86,7 +86,17 @@ void CPUInformation::initialise() noexcept hasAVX = (c & (1u << 28)) != 0; SystemStatsHelpers::doCPUID (a, b, c, d, 7); - hasAVX2 = (b & (1u << 5)) != 0; + hasAVX2 = (b & (1u << 5)) != 0; + hasAVX512F = (b & (1u << 16)) != 0; + hasAVX512DQ = (b & (1u << 17)) != 0; + hasAVX512IFMA = (b & (1u << 21)) != 0; + hasAVX512PF = (b & (1u << 26)) != 0; + hasAVX512ER = (b & (1u << 27)) != 0; + hasAVX512CD = (b & (1u << 28)) != 0; + hasAVX512BW = (b & (1u << 30)) != 0; + hasAVX512VL = (b & (1u << 31)) != 0; + hasAVX512VBMI = (c & (1u << 1)) != 0; + hasAVX512VPOPCNTDQ = (c & (1u << 14)) != 0; #endif numLogicalCPUs = (int) [[NSProcessInfo processInfo] activeProcessorCount]; diff --git a/modules/juce_core/native/juce_win32_SystemStats.cpp b/modules/juce_core/native/juce_win32_SystemStats.cpp index 1f8d755543..28ad6cc30b 100644 --- a/modules/juce_core/native/juce_win32_SystemStats.cpp +++ b/modules/juce_core/native/juce_win32_SystemStats.cpp @@ -151,7 +151,17 @@ void CPUInformation::initialise() noexcept callCPUID (info, 7); - hasAVX2 = (info[1] & (1 << 5)) != 0; + hasAVX2 = (info[1] & (1 << 5)) != 0; + hasAVX512F = (info[1] & (1u << 16)) != 0; + hasAVX512DQ = (info[1] & (1u << 17)) != 0; + hasAVX512IFMA = (info[1] & (1u << 21)) != 0; + hasAVX512PF = (info[1] & (1u << 26)) != 0; + hasAVX512ER = (info[1] & (1u << 27)) != 0; + hasAVX512CD = (info[1] & (1u << 28)) != 0; + hasAVX512BW = (info[1] & (1u << 30)) != 0; + hasAVX512VL = (info[1] & (1u << 31)) != 0; + hasAVX512VBMI = (info[2] & (1u << 1)) != 0; + hasAVX512VPOPCNTDQ = (info[2] & (1u << 14)) != 0; SYSTEM_INFO systemInfo; GetNativeSystemInfo (&systemInfo); diff --git a/modules/juce_core/system/juce_SystemStats.cpp b/modules/juce_core/system/juce_SystemStats.cpp index cbc7aa1ebc..7d1347413e 100644 --- a/modules/juce_core/system/juce_SystemStats.cpp +++ b/modules/juce_core/system/juce_SystemStats.cpp @@ -90,9 +90,14 @@ struct CPUInformation 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, hasNeon = false; + bool hasMMX = false, hasSSE = false, hasSSE2 = false, hasSSE3 = false, + has3DNow = false, hasSSSE3 = false, hasSSE41 = false, + hasSSE42 = false, hasAVX = false, hasAVX2 = false, + hasAVX512F = false, hasAVX512BW = false, hasAVX512CD = false, + hasAVX512DQ = false, hasAVX512ER = false, hasAVX512IFMA = false, + hasAVX512PF = false, hasAVX512VBMI = false, hasAVX512VL = false, + hasAVX512VPOPCNTDQ = false, + hasNeon = false; }; static const CPUInformation& getCPUInformation() noexcept @@ -113,6 +118,16 @@ bool SystemStats::hasSSE41() noexcept { return getCPUInformation().has bool SystemStats::hasSSE42() noexcept { return getCPUInformation().hasSSE42; } bool SystemStats::hasAVX() noexcept { return getCPUInformation().hasAVX; } bool SystemStats::hasAVX2() noexcept { return getCPUInformation().hasAVX2; } +bool SystemStats::hasAVX512F() noexcept { return getCPUInformation().hasAVX512F; } +bool SystemStats::hasAVX512BW() noexcept { return getCPUInformation().hasAVX512BW; } +bool SystemStats::hasAVX512CD() noexcept { return getCPUInformation().hasAVX512CD; } +bool SystemStats::hasAVX512DQ() noexcept { return getCPUInformation().hasAVX512DQ; } +bool SystemStats::hasAVX512ER() noexcept { return getCPUInformation().hasAVX512ER; } +bool SystemStats::hasAVX512IFMA() noexcept { return getCPUInformation().hasAVX512IFMA; } +bool SystemStats::hasAVX512PF() noexcept { return getCPUInformation().hasAVX512PF; } +bool SystemStats::hasAVX512VBMI() noexcept { return getCPUInformation().hasAVX512VBMI; } +bool SystemStats::hasAVX512VL() noexcept { return getCPUInformation().hasAVX512VL; } +bool SystemStats::hasAVX512VPOPCNTDQ() noexcept { return getCPUInformation().hasAVX512VPOPCNTDQ; } bool SystemStats::hasNeon() noexcept { return getCPUInformation().hasNeon; } diff --git a/modules/juce_core/system/juce_SystemStats.h b/modules/juce_core/system/juce_SystemStats.h index d50983ca56..8e441a9d61 100644 --- a/modules/juce_core/system/juce_SystemStats.h +++ b/modules/juce_core/system/juce_SystemStats.h @@ -168,17 +168,27 @@ public: */ static String getCpuModel(); - static bool hasMMX() noexcept; /**< Returns true if Intel MMX instructions are available. */ - static bool has3DNow() noexcept; /**< Returns true if AMD 3DNOW instructions are available. */ - static bool hasSSE() noexcept; /**< Returns true if Intel SSE instructions are available. */ - static bool hasSSE2() noexcept; /**< Returns true if Intel SSE2 instructions are available. */ - static bool hasSSE3() noexcept; /**< Returns true if Intel SSE3 instructions are available. */ - static bool hasSSSE3() noexcept; /**< Returns true if Intel SSSE3 instructions are available. */ - static bool hasSSE41() noexcept; /**< Returns true if Intel SSE4.1 instructions are available. */ - static bool hasSSE42() noexcept; /**< Returns true if Intel SSE4.2 instructions are available. */ - static bool hasAVX() noexcept; /**< Returns true if Intel AVX instructions are available. */ - static bool hasAVX2() noexcept; /**< Returns true if Intel AVX2 instructions are available. */ - static bool hasNeon() noexcept; /**< Returns true if ARM NEON instructions are available. */ + static bool hasMMX() noexcept; /**< Returns true if Intel MMX instructions are available. */ + static bool has3DNow() noexcept; /**< Returns true if AMD 3DNOW instructions are available. */ + static bool hasSSE() noexcept; /**< Returns true if Intel SSE instructions are available. */ + static bool hasSSE2() noexcept; /**< Returns true if Intel SSE2 instructions are available. */ + static bool hasSSE3() noexcept; /**< Returns true if Intel SSE3 instructions are available. */ + static bool hasSSSE3() noexcept; /**< Returns true if Intel SSSE3 instructions are available. */ + static bool hasSSE41() noexcept; /**< Returns true if Intel SSE4.1 instructions are available. */ + static bool hasSSE42() noexcept; /**< Returns true if Intel SSE4.2 instructions are available. */ + static bool hasAVX() noexcept; /**< Returns true if Intel AVX instructions are available. */ + static bool hasAVX2() noexcept; /**< Returns true if Intel AVX2 instructions are available. */ + static bool hasAVX512F() noexcept; /**< Returns true if Intel AVX-512 Foundation instructions are available. */ + static bool hasAVX512BW() noexcept; /**< Returns true if Intel AVX-512 Byte and Word instructions are available. */ + static bool hasAVX512CD() noexcept; /**< Returns true if Intel AVX-512 Conflict Detection instructions are available. */ + static bool hasAVX512DQ() noexcept; /**< Returns true if Intel AVX-512 Doubleword and Quadword instructions are available. */ + static bool hasAVX512ER() noexcept; /**< Returns true if Intel AVX-512 Exponential and Reciprocal instructions are available. */ + static bool hasAVX512IFMA() noexcept; /**< Returns true if Intel AVX-512 Integer Fused Multiply-Add instructions are available. */ + static bool hasAVX512PF() noexcept; /**< Returns true if Intel AVX-512 Prefetch instructions are available. */ + static bool hasAVX512VBMI() noexcept; /**< Returns true if Intel AVX-512 Vector Bit Manipulation instructions are available. */ + static bool hasAVX512VL() noexcept; /**< Returns true if Intel AVX-512 Vector Length instructions are available. */ + static bool hasAVX512VPOPCNTDQ() noexcept; /**< Returns true if Intel AVX-512 Vector Population Count Double and Quad-word instructions are available. */ + static bool hasNeon() noexcept; /**< Returns true if ARM NEON instructions are available. */ //============================================================================== /** Finds out how much RAM is in the machine.