From 628506e2665bc4869774556eb16f18bd01beed48 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 8 May 2020 22:25:13 +0700 Subject: [PATCH] ICpuInfo refactoring. --- src/backend/cpu/Cpu.cpp | 27 +--- src/backend/cpu/cpu.cmake | 11 +- src/backend/cpu/interfaces/ICpuInfo.h | 15 +++ src/backend/cpu/platform/AdvancedCpuInfo.cpp | 91 +------------- src/backend/cpu/platform/AdvancedCpuInfo.h | 22 +--- src/backend/cpu/platform/BasicCpuInfo.cpp | 115 ++++++++++-------- src/backend/cpu/platform/BasicCpuInfo.h | 21 ++-- src/backend/cpu/platform/BasicCpuInfo_arm.cpp | 4 +- src/backend/cpu/platform/HwlocCpuInfo.cpp | 6 +- src/backend/cpu/platform/HwlocCpuInfo.h | 4 +- 10 files changed, 110 insertions(+), 206 deletions(-) diff --git a/src/backend/cpu/Cpu.cpp b/src/backend/cpu/Cpu.cpp index a11c4c567..a6c629729 100644 --- a/src/backend/cpu/Cpu.cpp +++ b/src/backend/cpu/Cpu.cpp @@ -60,32 +60,7 @@ xmrig::ICpuInfo *xmrig::Cpu::info() rapidjson::Value xmrig::Cpu::toJSON(rapidjson::Document &doc) { - using namespace rapidjson; - auto &allocator = doc.GetAllocator(); - - ICpuInfo *i = info(); - Value cpu(kObjectType); - Assembly assembly(i->assembly()); - - cpu.AddMember("brand", StringRef(i->brand()), allocator); - cpu.AddMember("aes", i->hasAES(), allocator); - cpu.AddMember("avx2", i->hasAVX2(), allocator); - cpu.AddMember("x64", ICpuInfo::isX64(), allocator); - cpu.AddMember("l2", static_cast(i->L2()), allocator); - cpu.AddMember("l3", static_cast(i->L3()), allocator); - cpu.AddMember("cores", static_cast(i->cores()), allocator); - cpu.AddMember("threads", static_cast(i->threads()), allocator); - cpu.AddMember("packages", static_cast(i->packages()), allocator); - cpu.AddMember("nodes", static_cast(i->nodes()), allocator); - cpu.AddMember("backend", StringRef(i->backend()), allocator); - -# ifdef XMRIG_FEATURE_ASM - cpu.AddMember("assembly", StringRef(assembly.toString()), allocator); -# else - cpu.AddMember("assembly", "none", allocator); -# endif - - return cpu; + return info()->toJSON(doc); } diff --git a/src/backend/cpu/cpu.cmake b/src/backend/cpu/cpu.cmake index cb5431745..75ec1ad77 100644 --- a/src/backend/cpu/cpu.cmake +++ b/src/backend/cpu/cpu.cmake @@ -70,11 +70,8 @@ else() ) endif() - -if (NOT WITH_LIBCPUID) - if (XMRIG_ARM) - set(SOURCES_CPUID ${SOURCES_CPUID} src/backend/cpu/platform/BasicCpuInfo_arm.cpp) - else() - set(SOURCES_CPUID ${SOURCES_CPUID} src/backend/cpu/platform/BasicCpuInfo.cpp) - endif() +if (XMRIG_ARM) + list(APPEND SOURCES_CPUID src/backend/cpu/platform/BasicCpuInfo_arm.cpp) +else() + list(APPEND SOURCES_CPUID src/backend/cpu/platform/BasicCpuInfo.cpp) endif() diff --git a/src/backend/cpu/interfaces/ICpuInfo.h b/src/backend/cpu/interfaces/ICpuInfo.h index f5a35b2d0..badb44c0d 100644 --- a/src/backend/cpu/interfaces/ICpuInfo.h +++ b/src/backend/cpu/interfaces/ICpuInfo.h @@ -51,6 +51,19 @@ public: MSR_MOD_MAX }; + enum Flag : uint32_t { + FLAG_AES, + FLAG_AVX2, + FLAG_AVX512F, + FLAG_BMI2, + FLAG_OSXSAVE, + FLAG_PDPE1GB, + FLAG_SSE2, + FLAG_SSSE3, + FLAG_XOP, + FLAG_MAX + }; + virtual ~ICpuInfo() = default; # if defined(__x86_64__) || defined(_M_AMD64) || defined (__arm64__) || defined (__aarch64__) @@ -60,6 +73,7 @@ public: # endif virtual Assembly::Id assembly() const = 0; + virtual bool has(Flag feature) const = 0; virtual bool hasAES() const = 0; virtual bool hasAVX2() const = 0; virtual bool hasBMI2() const = 0; @@ -68,6 +82,7 @@ public: virtual const char *brand() const = 0; virtual CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const = 0; virtual MsrMod msrMod() const = 0; + virtual rapidjson::Value toJSON(rapidjson::Document &doc) const = 0; virtual size_t cores() const = 0; virtual size_t L2() const = 0; virtual size_t L3() const = 0; diff --git a/src/backend/cpu/platform/AdvancedCpuInfo.cpp b/src/backend/cpu/platform/AdvancedCpuInfo.cpp index 0632c1d19..941f60aa2 100644 --- a/src/backend/cpu/platform/AdvancedCpuInfo.cpp +++ b/src/backend/cpu/platform/AdvancedCpuInfo.cpp @@ -26,13 +26,6 @@ #include "3rdparty/libcpuid/libcpuid.h" -#ifdef _MSC_VER -# include -#else -# include -#endif - - #include #include #include @@ -40,59 +33,7 @@ #include -namespace xmrig { - - -static inline void cpu_brand_string(char out[64], const char *in) { - size_t pos = 0; - const size_t size = strlen(in); - - for (size_t i = 0; i < size; ++i) { - if (in[i] == ' ' && ((pos > 0 && out[pos - 1] == ' ') || pos == 0)) { - continue; - } - - out[pos++] = in[i]; - } - - if (pos > 0 && out[pos - 1] == ' ') { - out[pos - 1] = '\0'; - } -} - - -static inline void cpuid(uint32_t level, int32_t output[4]) -{ - memset(output, 0, sizeof(int32_t) * 4); - -# ifdef _MSC_VER - __cpuid(output, static_cast(level)); -# else - __cpuid_count(level, 0, output[0], output[1], output[2], output[3]); -# endif -} - - -static inline bool has_feature(uint32_t level, uint32_t reg, int32_t bit) -{ - int32_t cpu_info[4] = { 0 }; - cpuid(level, cpu_info); - - return (cpu_info[reg] & bit) != 0; -} - - -static inline bool has_pdpe1gb() -{ - return has_feature(0x80000001, 3, 1 << 26); -} - - -} // namespace xmrig - - -xmrig::AdvancedCpuInfo::AdvancedCpuInfo() : - m_pdpe1gb(has_pdpe1gb()) +xmrig::AdvancedCpuInfo::AdvancedCpuInfo() { struct cpu_raw_data_t raw = {}; struct cpu_id_t data = {}; @@ -100,18 +41,10 @@ xmrig::AdvancedCpuInfo::AdvancedCpuInfo() : cpuid_get_raw_data(&raw); cpu_identify(&raw, &data); - cpu_brand_string(m_brand, data.brand_str); snprintf(m_backend, sizeof m_backend, "libcpuid/%s", cpuid_lib_version()); - if (data.vendor == ::VENDOR_INTEL) { - m_vendor = VENDOR_INTEL; - } - else if (data.vendor == ::VENDOR_AMD) { - m_vendor = VENDOR_AMD; - } - m_threads = static_cast(data.total_logical_cpus); - m_packages = std::max(threads() / static_cast(data.num_logical_cpus), 1); + m_packages = std::max(m_threads / static_cast(data.num_logical_cpus), 1); m_cores = static_cast(data.num_cores) * m_packages; m_L3 = data.l3_cache > 0 ? static_cast(data.l3_cache) * m_packages : 0; @@ -134,26 +67,6 @@ xmrig::AdvancedCpuInfo::AdvancedCpuInfo() : m_L2 *= 1024; m_L3 *= 1024; - - if (data.flags[CPU_FEATURE_AES]) { - m_aes = true; - - if (m_vendor == VENDOR_AMD) { - if (data.ext_family >= 23) { - m_assembly = Assembly::RYZEN; - m_msrMod = MSR_MOD_RYZEN; - } - else { - m_assembly = Assembly::BULLDOZER; - } - } - else if (m_vendor == VENDOR_INTEL) { - m_assembly = Assembly::INTEL; - } - } - - m_avx2 = data.flags[CPU_FEATURE_AVX2] && data.flags[CPU_FEATURE_OSXSAVE]; - m_bmi2 = data.flags[CPU_FEATURE_BMI2]; } diff --git a/src/backend/cpu/platform/AdvancedCpuInfo.h b/src/backend/cpu/platform/AdvancedCpuInfo.h index 30ad3c584..9be075efe 100644 --- a/src/backend/cpu/platform/AdvancedCpuInfo.h +++ b/src/backend/cpu/platform/AdvancedCpuInfo.h @@ -26,13 +26,13 @@ #define XMRIG_ADVANCEDCPUINFO_H -#include "backend/cpu/interfaces/ICpuInfo.h" +#include "backend/cpu/platform/BasicCpuInfo.h" namespace xmrig { -class AdvancedCpuInfo : public ICpuInfo +class AdvancedCpuInfo : public BasicCpuInfo { public: AdvancedCpuInfo(); @@ -40,38 +40,20 @@ public: protected: CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const override; - inline Assembly::Id assembly() const override { return m_assembly; } - inline bool hasAES() const override { return m_aes; } - inline bool hasAVX2() const override { return m_avx2; } - inline bool hasBMI2() const override { return m_bmi2; } - inline bool hasOneGbPages() const override { return m_pdpe1gb; } inline const char *backend() const override { return m_backend; } - inline const char *brand() const override { return m_brand; } - inline MsrMod msrMod() const override { return m_msrMod; } inline size_t cores() const override { return m_cores; } inline size_t L2() const override { return m_L2; } inline size_t L3() const override { return m_L3; } - inline size_t nodes() const override { return 0; } inline size_t packages() const override { return m_packages; } inline size_t threads() const override { return m_threads; } - inline Vendor vendor() const override { return m_vendor; } private: - Assembly m_assembly; - bool m_aes = false; - bool m_avx2 = false; - bool m_bmi2 = false; bool m_L2_exclusive = false; char m_backend[32]{}; - char m_brand[64 + 5]{}; - const bool m_pdpe1gb = false; - MsrMod m_msrMod = MSR_MOD_NONE; size_t m_cores = 0; size_t m_L2 = 0; size_t m_L3 = 0; size_t m_packages = 1; - size_t m_threads = 0; - Vendor m_vendor = VENDOR_UNKNOWN; }; diff --git a/src/backend/cpu/platform/BasicCpuInfo.cpp b/src/backend/cpu/platform/BasicCpuInfo.cpp index d288ee28e..e1cda353f 100644 --- a/src/backend/cpu/platform/BasicCpuInfo.cpp +++ b/src/backend/cpu/platform/BasicCpuInfo.cpp @@ -33,28 +33,9 @@ # include #endif -#ifndef bit_AES -# define bit_AES (1 << 25) -#endif - -#ifndef bit_OSXSAVE -# define bit_OSXSAVE (1 << 27) -#endif - -#ifndef bit_AVX2 -# define bit_AVX2 (1 << 5) -#endif - -#ifndef bit_BMI2 -# define bit_BMI2 (1 << 8) -#endif - -#ifndef bit_PDPE1GB -# define bit_PDPE1GB (1 << 26) -#endif - #include "backend/cpu/platform/BasicCpuInfo.h" +#include "3rdparty/rapidjson/document.h" #include "crypto/common/Assembly.h" @@ -75,6 +56,11 @@ namespace xmrig { +static const std::array flagNames = { "aes", "avx2", "avx512f", "bmi2", "osxsave", "pdpe1gb", "sse2", "ssse3", "xop" }; +static const std::array msrNames = { "none", "ryzen", "intel", "custom" }; +std::bitset BasicCpuInfo::m_flags; + + static inline void cpuid(uint32_t level, int32_t output[4]) { memset(output, 0, sizeof(int32_t) * 4); @@ -133,42 +119,35 @@ static inline int32_t get_masked(int32_t val, int32_t h, int32_t l) } -static inline bool has_aes_ni() -{ - return has_feature(PROCESSOR_INFO, ECX_Reg, bit_AES); -} - - -static inline bool has_avx2() -{ - return has_feature(EXTENDED_FEATURES, EBX_Reg, bit_AVX2) && has_feature(PROCESSOR_INFO, ECX_Reg, bit_OSXSAVE); -} - - -static inline bool has_bmi2() -{ - return has_feature(EXTENDED_FEATURES, EBX_Reg, bit_BMI2); -} - - -static inline bool has_pdpe1gb() -{ - return has_feature(PROCESSOR_EXT_INFO, EDX_Reg, bit_PDPE1GB); -} +static inline bool has_osxsave() { return has_feature(PROCESSOR_INFO, ECX_Reg, 1 << 27); } +static inline bool has_aes_ni() { return has_feature(PROCESSOR_INFO, ECX_Reg, 1 << 25); } +static inline bool has_avx2() { return has_feature(EXTENDED_FEATURES, EBX_Reg, 1 << 5) && has_osxsave(); } +static inline bool has_avx512f() { return has_feature(EXTENDED_FEATURES, EBX_Reg, 1 << 16) && has_osxsave(); } +static inline bool has_bmi2() { return has_feature(EXTENDED_FEATURES, EBX_Reg, 1 << 8); } +static inline bool has_pdpe1gb() { return has_feature(PROCESSOR_EXT_INFO, EDX_Reg, 1 << 26); } +static inline bool has_sse2() { return has_feature(PROCESSOR_INFO, EDX_Reg, 1 << 26); } +static inline bool has_ssse3() { return has_feature(PROCESSOR_INFO, ECX_Reg, 1 << 9); } +static inline bool has_xop() { return has_feature(0x80000001, ECX_Reg, 1 << 11); } } // namespace xmrig xmrig::BasicCpuInfo::BasicCpuInfo() : - m_threads(std::thread::hardware_concurrency()), - m_aes(has_aes_ni()), - m_avx2(has_avx2()), - m_bmi2(has_bmi2()), - m_pdpe1gb(has_pdpe1gb()) + m_threads(std::thread::hardware_concurrency()) { cpu_brand_string(m_brand); + m_flags.set(FLAG_AES, has_aes_ni()); + m_flags.set(FLAG_AVX2, has_avx2()); + m_flags.set(FLAG_AVX512F, has_avx512f()); + m_flags.set(FLAG_BMI2, has_bmi2()); + m_flags.set(FLAG_OSXSAVE, has_osxsave()); + m_flags.set(FLAG_PDPE1GB, has_pdpe1gb()); + m_flags.set(FLAG_SSE2, has_sse2()); + m_flags.set(FLAG_SSSE3, has_ssse3()); + m_flags.set(FLAG_XOP, has_xop()); + # ifdef XMRIG_FEATURE_ASM if (hasAES()) { char vendor[13] = { 0 }; @@ -206,7 +185,7 @@ xmrig::BasicCpuInfo::BasicCpuInfo() : const char *xmrig::BasicCpuInfo::backend() const { - return "basic"; + return "basic/1"; } @@ -270,3 +249,43 @@ xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm, uint3 return CpuThreads(std::max(count / 2, 1), 1); } + + +rapidjson::Value xmrig::BasicCpuInfo::toJSON(rapidjson::Document &doc) const +{ + using namespace rapidjson; + auto &allocator = doc.GetAllocator(); + + Value out(kObjectType); + + out.AddMember("brand", StringRef(brand()), allocator); + out.AddMember("aes", hasAES(), allocator); + out.AddMember("avx2", hasAVX2(), allocator); + out.AddMember("x64", ICpuInfo::isX64(), allocator); + out.AddMember("l2", static_cast(L2()), allocator); + out.AddMember("l3", static_cast(L3()), allocator); + out.AddMember("cores", static_cast(cores()), allocator); + out.AddMember("threads", static_cast(threads()), allocator); + out.AddMember("packages", static_cast(packages()), allocator); + out.AddMember("nodes", static_cast(nodes()), allocator); + out.AddMember("backend", StringRef(backend()), allocator); + out.AddMember("msr", StringRef(msrNames[msrMod()]), allocator); + +# ifdef XMRIG_FEATURE_ASM + out.AddMember("assembly", StringRef(Assembly(assembly()).toString()), allocator); +# else + cpu.AddMember("assembly", "none", allocator); +# endif + + Value flags(kArrayType); + + for (size_t i = 0; i < flagNames.size(); ++i) { + if (m_flags.test(i)) { + flags.PushBack(StringRef(flagNames[i]), allocator); + } + } + + out.AddMember("flags", flags, allocator); + + return out; +} diff --git a/src/backend/cpu/platform/BasicCpuInfo.h b/src/backend/cpu/platform/BasicCpuInfo.h index b553e575e..4d0fa745d 100644 --- a/src/backend/cpu/platform/BasicCpuInfo.h +++ b/src/backend/cpu/platform/BasicCpuInfo.h @@ -29,6 +29,9 @@ #include "backend/cpu/interfaces/ICpuInfo.h" +#include + + namespace xmrig { @@ -40,12 +43,14 @@ public: protected: const char *backend() const override; CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const override; + rapidjson::Value toJSON(rapidjson::Document &doc) const override; inline Assembly::Id assembly() const override { return m_assembly; } - inline bool hasAES() const override { return m_aes; } - inline bool hasAVX2() const override { return m_avx2; } - inline bool hasBMI2() const override { return m_bmi2; } - inline bool hasOneGbPages() const override { return m_pdpe1gb; } + inline bool has(Flag flag) const override { return m_flags.test(flag); } + inline bool hasAES() const override { return has(FLAG_AES); } + inline bool hasAVX2() const override { return has(FLAG_AVX2); } + inline bool hasBMI2() const override { return has(FLAG_BMI2); } + inline bool hasOneGbPages() const override { return has(FLAG_PDPE1GB); } inline const char *brand() const override { return m_brand; } inline MsrMod msrMod() const override { return m_msrMod; } inline size_t cores() const override { return 0; } @@ -59,15 +64,13 @@ protected: protected: char m_brand[64 + 6]{}; size_t m_threads; + Vendor m_vendor = VENDOR_UNKNOWN; private: + static std::bitset m_flags; + Assembly m_assembly = Assembly::NONE; - bool m_aes = false; - const bool m_avx2 = false; - const bool m_bmi2 = false; - const bool m_pdpe1gb = false; MsrMod m_msrMod = MSR_MOD_NONE; - Vendor m_vendor = VENDOR_UNKNOWN; }; diff --git a/src/backend/cpu/platform/BasicCpuInfo_arm.cpp b/src/backend/cpu/platform/BasicCpuInfo_arm.cpp index 00f5f01f3..8c4bb63a4 100644 --- a/src/backend/cpu/platform/BasicCpuInfo_arm.cpp +++ b/src/backend/cpu/platform/BasicCpuInfo_arm.cpp @@ -46,9 +46,9 @@ xmrig::BasicCpuInfo::BasicCpuInfo() : # if __ARM_FEATURE_CRYPTO # if !defined(__APPLE__) - m_aes = getauxval(AT_HWCAP) & HWCAP_AES; + m_flags.set(FLAG_AES, getauxval(AT_HWCAP) & HWCAP_AES); # else - m_aes = true; + m_flags.set(FLAG_AES, true); # endif # endif } diff --git a/src/backend/cpu/platform/HwlocCpuInfo.cpp b/src/backend/cpu/platform/HwlocCpuInfo.cpp index 527284505..378d6858a 100644 --- a/src/backend/cpu/platform/HwlocCpuInfo.cpp +++ b/src/backend/cpu/platform/HwlocCpuInfo.cpp @@ -5,8 +5,8 @@ * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2019 XMR-Stak , - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig + * Copyright 2018-2020 SChernykh + * Copyright 2016-2020 XMRig * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -313,7 +313,7 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith size_t cacheHashes = ((L3 + extra) + (scratchpad / 2)) / scratchpad; # ifdef XMRIG_ALGO_CN_PICO - if (algorithm == Algorithm::CN_PICO_0 && (cacheHashes / PUs) >= 2) { + if (intensity && algorithm == Algorithm::CN_PICO_0 && (cacheHashes / PUs) >= 2) { intensity = 2; } # endif diff --git a/src/backend/cpu/platform/HwlocCpuInfo.h b/src/backend/cpu/platform/HwlocCpuInfo.h index c22291e85..3746f151e 100644 --- a/src/backend/cpu/platform/HwlocCpuInfo.h +++ b/src/backend/cpu/platform/HwlocCpuInfo.h @@ -5,8 +5,8 @@ * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee * Copyright 2017-2019 XMR-Stak , - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig + * Copyright 2018-2020 SChernykh + * Copyright 2016-2020 XMRig * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by