From ee4d980955f749e82e6b0bc944b155c7f00ab131 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 23 Sep 2018 17:51:56 +0300 Subject: [PATCH] Old static class Cpu replaced to interface ICpuInfo. --- CMakeLists.txt | 13 +- src/App.cpp | 2 +- src/Cpu.h | 66 --------- src/Summary.cpp | 18 +-- src/api/ApiRouter.cpp | 11 +- .../cpu/BasicCpuInfo.cpp} | 60 +++----- src/common/cpu/BasicCpuInfo.h | 70 ++++++++++ .../cpu/BasicCpuInfo_arm.cpp} | 34 ++--- src/{Cpu_unix.cpp => common/cpu/Cpu.cpp} | 45 +++--- src/{Cpu_mac.cpp => common/cpu/Cpu.h} | 30 ++-- src/common/interfaces/ICpuInfo.h | 59 ++++++++ src/common/xmrig.h | 8 ++ src/core/Config.cpp | 18 +-- src/core/Controller.cpp | 2 +- src/{Cpu.cpp => core/cpu/AdvancedCpuInfo.cpp} | 132 ++++++++---------- src/core/cpu/AdvancedCpuInfo.h | 75 ++++++++++ src/{Cpu_win.cpp => core/cpu/Cpu.cpp} | 40 ++++-- src/workers/Worker.cpp | 4 +- 18 files changed, 406 insertions(+), 281 deletions(-) delete mode 100644 src/Cpu.h rename src/{Cpu_stub.cpp => common/cpu/BasicCpuInfo.cpp} (77%) create mode 100644 src/common/cpu/BasicCpuInfo.h rename src/{Cpu_arm.cpp => common/cpu/BasicCpuInfo_arm.cpp} (74%) rename src/{Cpu_unix.cpp => common/cpu/Cpu.cpp} (71%) rename src/{Cpu_mac.cpp => common/cpu/Cpu.h} (75%) create mode 100644 src/common/interfaces/ICpuInfo.h rename src/{Cpu.cpp => core/cpu/AdvancedCpuInfo.cpp} (57%) create mode 100644 src/core/cpu/AdvancedCpuInfo.h rename src/{Cpu_win.cpp => core/cpu/Cpu.cpp} (69%) diff --git a/CMakeLists.txt b/CMakeLists.txt index b779b74d..6f7d6291 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ set(HEADERS src/common/config/ConfigLoader.h src/common/config/ConfigWatcher.h src/common/Console.h + src/common/cpu/Cpu.h src/common/crypto/Algorithm.h src/common/crypto/keccak.h src/common/interfaces/IClientListener.h @@ -27,6 +28,7 @@ set(HEADERS src/common/interfaces/IConfigCreator.h src/common/interfaces/IConsoleListener.h src/common/interfaces/IControllerListener.h + src/common/interfaces/ICpuInfo.h src/common/interfaces/ILogBackend.h src/common/interfaces/IStrategy.h src/common/interfaces/IStrategyListener.h @@ -49,7 +51,6 @@ set(HEADERS src/common/xmrig.h src/core/ConfigLoader_platform.h src/core/Controller.h - src/Cpu.h src/interfaces/IJobResultListener.h src/interfaces/IThread.h src/interfaces/IWorker.h @@ -135,7 +136,6 @@ if (WIN32) res/app.rc src/App_win.cpp src/common/Platform_win.cpp - src/Cpu_win.cpp src/Mem_win.cpp ) @@ -145,14 +145,12 @@ elseif (APPLE) set(SOURCES_OS src/App_unix.cpp src/common/Platform_mac.cpp - src/Cpu_mac.cpp src/Mem_unix.cpp ) else() set(SOURCES_OS src/App_unix.cpp src/common/Platform_unix.cpp - src/Cpu_unix.cpp src/Mem_unix.cpp ) @@ -184,14 +182,15 @@ if (WITH_LIBCPUID) include_directories(src/3rdparty/libcpuid) set(CPUID_LIB cpuid) - set(SOURCES_CPUID src/Cpu.cpp) + set(SOURCES_CPUID src/core/cpu/AdvancedCpuInfo.h src/core/cpu/AdvancedCpuInfo.cpp src/core/cpu/Cpu.cpp) else() add_definitions(/DXMRIG_NO_LIBCPUID) + set(SOURCES_CPUID src/common/cpu/BasicCpuInfo.h src/common/cpu/Cpu.cpp) if (XMRIG_ARM) - set(SOURCES_CPUID src/Cpu_arm.cpp) + set(SOURCES_CPUID ${SOURCES_CPUID} src/common/cpu/BasicCpuInfo_arm.cpp) else() - set(SOURCES_CPUID src/Cpu_stub.cpp) + set(SOURCES_CPUID ${SOURCES_CPUID} src/common/cpu/BasicCpuInfo.cpp) endif() endif() diff --git a/src/App.cpp b/src/App.cpp index adcc5752..134e4ef5 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -29,11 +29,11 @@ #include "api/Api.h" #include "App.h" #include "common/Console.h" +#include "common/cpu/Cpu.h" #include "common/log/Log.h" #include "common/Platform.h" #include "core/Config.h" #include "core/Controller.h" -#include "Cpu.h" #include "crypto/CryptoNight.h" #include "Mem.h" #include "net/Network.h" diff --git a/src/Cpu.h b/src/Cpu.h deleted file mode 100644 index a125bae8..00000000 --- a/src/Cpu.h +++ /dev/null @@ -1,66 +0,0 @@ -/* XMRig - * Copyright 2010 Jeff Garzik - * Copyright 2012-2014 pooler - * Copyright 2014 Lucas Jones - * Copyright 2014-2016 Wolf9466 - * Copyright 2016 Jay D Dee - * Copyright 2017-2018 XMR-Stak , - * Copyright 2016-2018 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 - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __CPU_H__ -#define __CPU_H__ - - -#include - - -class Cpu -{ -public: - enum Flags { - X86_64 = 1, - AES = 2, - BMI2 = 4 - }; - - static size_t optimalThreadsCount(size_t size, int maxCpuUsage); - static void init(); - - static inline bool hasAES() { return (m_flags & AES) != 0; } - static inline bool isX64() { return (m_flags & X86_64) != 0; } - static inline const char *brand() { return m_brand; } - static inline int cores() { return m_totalCores; } - static inline int l2() { return m_l2_cache; } - static inline int l3() { return m_l3_cache; } - static inline int sockets() { return m_sockets; } - static inline int threads() { return m_totalThreads; } - -private: - static void initCommon(); - - static bool m_l2_exclusive; - static char m_brand[64]; - static int m_flags; - static int m_l2_cache; - static int m_l3_cache; - static int m_sockets; - static int m_totalCores; - static size_t m_totalThreads; -}; - - -#endif /* __CPU_H__ */ diff --git a/src/Summary.cpp b/src/Summary.cpp index de6b1234..ba220e5b 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -27,11 +27,11 @@ #include +#include "common/cpu/Cpu.h" #include "common/log/Log.h" #include "common/net/Pool.h" #include "core/Config.h" #include "core/Controller.h" -#include "Cpu.h" #include "Mem.h" #include "Summary.h" #include "version.h" @@ -52,21 +52,23 @@ static void print_memory(xmrig::Config *config) { static void print_cpu(xmrig::Config *config) { + using namespace xmrig; + if (config->isColors()) { Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s (%d)") " %sx64 %sAES", "CPU", - Cpu::brand(), - Cpu::sockets(), - Cpu::isX64() ? "\x1B[1;32m" : "\x1B[1;31m-", - Cpu::hasAES() ? "\x1B[1;32m" : "\x1B[1;31m-"); + Cpu::info()->brand(), + Cpu::info()->sockets(), + Cpu::info()->isX64() ? "\x1B[1;32m" : "\x1B[1;31m-", + Cpu::info()->hasAES() ? "\x1B[1;32m" : "\x1B[1;31m-"); # ifndef XMRIG_NO_LIBCPUID - Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%.1f MB/%.1f MB"), "CPU L2/L3", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0); + Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%.1f MB/%.1f MB"), "CPU L2/L3", Cpu::info()->L2() / 1024.0, Cpu::info()->L3() / 1024.0); # endif } else { - Log::i()->text(" * %-13s%s (%d) %sx64 %sAES", "CPU", Cpu::brand(), Cpu::sockets(), Cpu::isX64() ? "" : "-", Cpu::hasAES() ? "" : "-"); + Log::i()->text(" * %-13s%s (%d) %sx64 %sAES", "CPU", Cpu::info()->brand(), Cpu::info()->sockets(), Cpu::info()->isX64() ? "" : "-", Cpu::info()->hasAES() ? "" : "-"); # ifndef XMRIG_NO_LIBCPUID - Log::i()->text(" * %-13s%.1f MB/%.1f MB", "CPU L2/L3", Cpu::l2() / 1024.0, Cpu::l3() / 1024.0); + Log::i()->text(" * %-13s%.1f MB/%.1f MB", "CPU L2/L3", Cpu::info()->L2() / 1024.0, Cpu::info()->L3() / 1024.0); # endif } } diff --git a/src/api/ApiRouter.cpp b/src/api/ApiRouter.cpp index 2c62696a..dd7accf6 100644 --- a/src/api/ApiRouter.cpp +++ b/src/api/ApiRouter.cpp @@ -35,12 +35,12 @@ #include "api/ApiRouter.h" #include "common/api/HttpReply.h" #include "common/api/HttpRequest.h" +#include "common/cpu/Cpu.h" #include "common/crypto/keccak.h" #include "common/net/Job.h" #include "common/Platform.h" #include "core/Config.h" #include "core/Controller.h" -#include "Cpu.h" #include "interfaces/IThread.h" #include "rapidjson/document.h" #include "rapidjson/prettywriter.h" @@ -238,13 +238,14 @@ void ApiRouter::getIdentify(rapidjson::Document &doc) const void ApiRouter::getMiner(rapidjson::Document &doc) const { + using namespace xmrig; auto &allocator = doc.GetAllocator(); rapidjson::Value cpu(rapidjson::kObjectType); - cpu.AddMember("brand", rapidjson::StringRef(Cpu::brand()), allocator); - cpu.AddMember("aes", Cpu::hasAES(), allocator); - cpu.AddMember("x64", Cpu::isX64(), allocator); - cpu.AddMember("sockets", Cpu::sockets(), allocator); + cpu.AddMember("brand", rapidjson::StringRef(Cpu::info()->brand()), allocator); + cpu.AddMember("aes", Cpu::info()->hasAES(), allocator); + cpu.AddMember("x64", Cpu::info()->isX64(), allocator); + cpu.AddMember("sockets", Cpu::info()->sockets(), allocator); doc.AddMember("version", APP_VERSION, allocator); doc.AddMember("kind", APP_KIND, allocator); diff --git a/src/Cpu_stub.cpp b/src/common/cpu/BasicCpuInfo.cpp similarity index 77% rename from src/Cpu_stub.cpp rename to src/common/cpu/BasicCpuInfo.cpp index 8b27ad65..66af53cc 100644 --- a/src/Cpu_stub.cpp +++ b/src/common/cpu/BasicCpuInfo.cpp @@ -21,6 +21,9 @@ * along with this program. If not, see . */ +#include +#include + #ifdef _MSC_VER # include @@ -32,14 +35,8 @@ # define bit_AES (1 << 25) #endif -#ifndef bit_BMI2 -# define bit_BMI2 (1 << 8) -#endif -#include - - -#include "Cpu.h" +#include "common/cpu/BasicCpuInfo.h" #define VENDOR_ID (0) @@ -96,43 +93,18 @@ static inline bool has_aes_ni() } -static inline bool has_bmi2() { - int cpu_info[4] = { 0 }; - cpuid(EXTENDED_FEATURES, cpu_info); - - return (cpu_info[EBX_Reg] & bit_BMI2) != 0; -} - - -char Cpu::m_brand[64] = { 0 }; -int Cpu::m_flags = 0; -int Cpu::m_l2_cache = 0; -int Cpu::m_l3_cache = 0; -int Cpu::m_sockets = 1; -int Cpu::m_totalCores = 0; -size_t Cpu::m_totalThreads = 0; - - -size_t Cpu::optimalThreadsCount(size_t size, int maxCpuUsage) -{ - const size_t count = m_totalThreads / 2; - return count < 1 ? 1 : count; -} - - -void Cpu::initCommon() +xmrig::BasicCpuInfo::BasicCpuInfo() : + m_aes(has_aes_ni()), + m_brand(), + m_threads(std::thread::hardware_concurrency()) { cpu_brand_string(m_brand); - -# if defined(__x86_64__) || defined(_M_AMD64) - m_flags |= X86_64; -# endif - - if (has_aes_ni()) { - m_flags |= AES; - } - - if (has_bmi2()) { - m_flags |= BMI2; - } +} + + +size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const +{ + const size_t count = threads() / 2; + + return count < 1 ? 1 : count; } diff --git a/src/common/cpu/BasicCpuInfo.h b/src/common/cpu/BasicCpuInfo.h new file mode 100644 index 00000000..f9d710d6 --- /dev/null +++ b/src/common/cpu/BasicCpuInfo.h @@ -0,0 +1,70 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_BASICCPUINFO_H +#define XMRIG_BASICCPUINFO_H + + +#include "common/interfaces/ICpuInfo.h" + + +namespace xmrig { + + +class BasicCpuInfo : public ICpuInfo +{ +public: + BasicCpuInfo(); + +protected: + size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const override; + + inline Assembly assembly() const override { return ASM_NONE; } + inline bool hasAES() const override { return m_aes; } + inline bool isSupported() const override { return true; } + inline const char *brand() const override { return m_brand; } + inline int32_t cores() const override { return -1; } + inline int32_t L2() const override { return -1; } + inline int32_t L3() const override { return -1; } + inline int32_t nodes() const override { return -1; } + inline int32_t sockets() const override { return 1; } + inline int32_t threads() const override { return m_threads; } + +# if defined(__x86_64__) || defined(_M_AMD64) || defined (__arm64__) || defined (__aarch64__) + inline bool isX64() const override { return true; } +# else + inline bool isX64() const override { return false; } +# endif + +private: + bool m_aes; + char m_brand[64]; + int32_t m_threads; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_BASICCPUINFO_H */ diff --git a/src/Cpu_arm.cpp b/src/common/cpu/BasicCpuInfo_arm.cpp similarity index 74% rename from src/Cpu_arm.cpp rename to src/common/cpu/BasicCpuInfo_arm.cpp index 3e259d0d..34eb7388 100644 --- a/src/Cpu_arm.cpp +++ b/src/common/cpu/BasicCpuInfo_arm.cpp @@ -21,37 +21,27 @@ * along with this program. If not, see . */ - #include +#include -#include "Cpu.h" +#include "common/cpu/BasicCpuInfo.h" -char Cpu::m_brand[64] = { 0 }; -int Cpu::m_flags = 0; -int Cpu::m_l2_cache = 0; -int Cpu::m_l3_cache = 0; -int Cpu::m_sockets = 1; -int Cpu::m_totalCores = 0; -size_t Cpu::m_totalThreads = 0; - - -size_t Cpu::optimalThreadsCount(size_t size, int maxCpuUsage) -{ - return m_totalThreads; -} - - -void Cpu::initCommon() +xmrig::BasicCpuInfo::BasicCpuInfo() : + m_aes(false), + m_brand(), + m_threads(std::thread::hardware_concurrency()) { memcpy(m_brand, "Unknown", 7); -# if defined (__arm64__) || defined (__aarch64__) - m_flags |= X86_64; -# endif - # if __ARM_FEATURE_CRYPTO m_flags |= AES; # endif } + + +size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const +{ + return threads(); +} diff --git a/src/Cpu_unix.cpp b/src/common/cpu/Cpu.cpp similarity index 71% rename from src/Cpu_unix.cpp rename to src/common/cpu/Cpu.cpp index b895c897..b1bb28ac 100644 --- a/src/Cpu_unix.cpp +++ b/src/common/cpu/Cpu.cpp @@ -22,33 +22,36 @@ */ -#ifdef __FreeBSD__ -# include -# include -# include -# include -#endif +#include -#include -#include -#include -#include +#include "common/cpu/BasicCpuInfo.h" +#include "common/cpu/Cpu.h" -#include "Cpu.h" +static xmrig::ICpuInfo *cpuInfo = nullptr; -#ifdef __FreeBSD__ -typedef cpuset_t cpu_set_t; -#endif - - -void Cpu::init() +xmrig::ICpuInfo *xmrig::Cpu::info() { -# ifdef XMRIG_NO_LIBCPUID - m_totalThreads = sysconf(_SC_NPROCESSORS_CONF); -# endif + assert(cpuInfo != nullptr); - initCommon(); + return cpuInfo; +} + + +void xmrig::Cpu::init() +{ + assert(cpuInfo == nullptr); + + cpuInfo = new BasicCpuInfo(); +} + + +void xmrig::Cpu::release() +{ + assert(cpuInfo != nullptr); + + delete cpuInfo; + cpuInfo = nullptr; } diff --git a/src/Cpu_mac.cpp b/src/common/cpu/Cpu.h similarity index 75% rename from src/Cpu_mac.cpp rename to src/common/cpu/Cpu.h index 085148bc..1d5a9fb1 100644 --- a/src/Cpu_mac.cpp +++ b/src/common/cpu/Cpu.h @@ -4,7 +4,7 @@ * Copyright 2014 Lucas Jones * Copyright 2014-2016 Wolf9466 * Copyright 2016 Jay D Dee - * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , * Copyright 2016-2018 XMRig , * * This program is free software: you can redistribute it and/or modify @@ -21,20 +21,26 @@ * along with this program. If not, see . */ - -#include -#include -#include +#ifndef XMRIG_CPU_H +#define XMRIG_CPU_H -#include "Cpu.h" +#include "common/interfaces/ICpuInfo.h" -void Cpu::init() +namespace xmrig { + + +class Cpu { -# ifdef XMRIG_NO_LIBCPUID - m_totalThreads = sysconf(_SC_NPROCESSORS_CONF); -# endif +public: + static ICpuInfo *info(); + static void init(); + static void release(); +}; - initCommon(); -} + +} /* namespace xmrig */ + + +#endif /* XMRIG_CPU_H */ diff --git a/src/common/interfaces/ICpuInfo.h b/src/common/interfaces/ICpuInfo.h new file mode 100644 index 00000000..c959bf52 --- /dev/null +++ b/src/common/interfaces/ICpuInfo.h @@ -0,0 +1,59 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2018 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CPUINFO_H +#define XMRIG_CPUINFO_H + + +#include + + +#include "common/xmrig.h" + + +namespace xmrig { + + +class ICpuInfo +{ +public: + virtual ~ICpuInfo() {} + + virtual bool hasAES() const = 0; + virtual bool isSupported() const = 0; + virtual bool isX64() const = 0; + virtual const char *brand() const = 0; + virtual int32_t cores() const = 0; + virtual int32_t L2() const = 0; + virtual int32_t L3() const = 0; + virtual int32_t nodes() const = 0; + virtual int32_t sockets() const = 0; + virtual int32_t threads() const = 0; + virtual size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const = 0; + virtual xmrig::Assembly assembly() const = 0; +}; + + +} /* namespace xmrig */ + + +#endif // XMRIG_CPUINFO_H diff --git a/src/common/xmrig.h b/src/common/xmrig.h index e1c7702e..820bc4fb 100644 --- a/src/common/xmrig.h +++ b/src/common/xmrig.h @@ -94,6 +94,14 @@ enum OclVendor { }; +enum Assembly { + ASM_NONE, + ASM_AUTO, + ASM_INTEL, + ASM_RYZEN +}; + + } /* namespace xmrig */ diff --git a/src/core/Config.cpp b/src/core/Config.cpp index 0380c26d..d99bfb09 100644 --- a/src/core/Config.cpp +++ b/src/core/Config.cpp @@ -27,9 +27,9 @@ #include "common/config/ConfigLoader.h" +#include "common/cpu/Cpu.h" #include "core/Config.h" #include "core/ConfigCreator.h" -#include "Cpu.h" #include "crypto/CryptoNight_constants.h" #include "rapidjson/document.h" #include "rapidjson/filewritestream.h" @@ -153,7 +153,7 @@ bool xmrig::Config::finalize() if (!m_threads.cpu.empty()) { m_threads.mode = Advanced; - const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT; + const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT; for (size_t i = 0; i < m_threads.cpu.size(); ++i) { m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm.algo(), m_threads.cpu[i], m_priority, softAES)); @@ -168,10 +168,10 @@ bool xmrig::Config::finalize() const size_t size = CpuThread::multiway(av) * cn_select_memory(m_algorithm.algo()) / 1024; if (!m_threads.count) { - m_threads.count = Cpu::optimalThreadsCount(size, m_maxCpuUsage); + m_threads.count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage); } else if (m_safe) { - const size_t count = Cpu::optimalThreadsCount(size, m_maxCpuUsage); + const size_t count = Cpu::info()->optimalThreadsCount(size, m_maxCpuUsage); if (m_threads.count > count) { m_threads.count = count; } @@ -232,7 +232,7 @@ bool xmrig::Config::parseString(int key, const char *arg) case ThreadsKey: /* --threads */ if (strncmp(arg, "all", 3) == 0) { - m_threads.count = Cpu::threads(); + m_threads.count = Cpu::info()->threads(); return true; } @@ -339,10 +339,10 @@ xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const # endif if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) { - return Cpu::hasAES() ? AV_SINGLE : AV_SINGLE_SOFT; + return Cpu::info()->hasAES() ? AV_SINGLE : AV_SINGLE_SOFT; } - if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV_DOUBLE) { + if (m_safe && !Cpu::info()->hasAES() && m_algoVariant <= AV_DOUBLE) { return static_cast(m_algoVariant + 2); } @@ -354,10 +354,10 @@ xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const xmrig::AlgoVariant xmrig::Config::getAlgoVariantLite() const { if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) { - return Cpu::hasAES() ? AV_DOUBLE : AV_DOUBLE_SOFT; + return Cpu::info()->hasAES() ? AV_DOUBLE : AV_DOUBLE_SOFT; } - if (m_safe && !Cpu::hasAES() && m_algoVariant <= AV_DOUBLE) { + if (m_safe && !Cpu::info()->hasAES() && m_algoVariant <= AV_DOUBLE) { return static_cast(m_algoVariant + 2); } diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index ce73f037..792ac939 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -26,6 +26,7 @@ #include "common/config/ConfigLoader.h" +#include "common/cpu/Cpu.h" #include "common/interfaces/IControllerListener.h" #include "common/log/ConsoleLog.h" #include "common/log/FileLog.h" @@ -33,7 +34,6 @@ #include "common/Platform.h" #include "core/Config.h" #include "core/Controller.h" -#include "Cpu.h" #include "net/Network.h" diff --git a/src/Cpu.cpp b/src/core/cpu/AdvancedCpuInfo.cpp similarity index 57% rename from src/Cpu.cpp rename to src/core/cpu/AdvancedCpuInfo.cpp index eebe585d..009a2bcb 100644 --- a/src/Cpu.cpp +++ b/src/core/cpu/AdvancedCpuInfo.cpp @@ -21,65 +21,24 @@ * along with this program. If not, see . */ - #include #include #include +#include -#include "Cpu.h" +#include "core/cpu/AdvancedCpuInfo.h" -bool Cpu::m_l2_exclusive = false; -char Cpu::m_brand[64] = { 0 }; -int Cpu::m_flags = 0; -int Cpu::m_l2_cache = 0; -int Cpu::m_l3_cache = 0; -int Cpu::m_sockets = 1; -int Cpu::m_totalCores = 0; -size_t Cpu::m_totalThreads = 0; - - -size_t Cpu::optimalThreadsCount(size_t size, int maxCpuUsage) -{ - if (m_totalThreads == 1) { - return 1; - } - - size_t cache = 0; - if (m_l3_cache) { - cache = m_l2_exclusive ? (m_l2_cache + m_l3_cache) : m_l3_cache; - } - else { - cache = m_l2_cache; - } - - size_t count = 0; - - if (cache) { - count = cache / size; - - if (cache % size >= size / 2) { - count++; - } - } - else { - count = m_totalThreads / 2; - } - - if (count > m_totalThreads) { - count = m_totalThreads; - } - - if (((float) count / m_totalThreads * 100) > maxCpuUsage) { - count = (int) ceil((float) m_totalThreads * (maxCpuUsage / 100.0)); - } - - return count < 1 ? 1 : count; -} - - -void Cpu::initCommon() +xmrig::AdvancedCpuInfo::AdvancedCpuInfo() : + m_aes(false), + m_L2_exclusive(false), + m_brand(), + m_cores(0), + m_L2(0), + m_L3(0), + m_sockets(1), + m_threads(std::thread::hardware_concurrency()) { struct cpu_raw_data_t raw = { 0 }; struct cpu_id_t data = { 0 }; @@ -89,40 +48,67 @@ void Cpu::initCommon() strncpy(m_brand, data.brand_str, sizeof(m_brand) - 1); - m_totalThreads = data.total_logical_cpus; - m_sockets = m_totalThreads / data.num_logical_cpus; - + m_sockets = threads() / data.num_logical_cpus; if (m_sockets == 0) { m_sockets = 1; } - m_totalCores = data.num_cores * m_sockets; - m_l3_cache = data.l3_cache > 0 ? data.l3_cache * m_sockets : 0; + m_cores = data.num_cores * m_sockets; + m_L3 = data.l3_cache > 0 ? data.l3_cache * m_sockets : 0; // Workaround for AMD CPUs https://github.com/anrieff/libcpuid/issues/97 if (data.vendor == VENDOR_AMD && data.ext_family >= 0x15 && data.ext_family < 0x17) { - m_l2_cache = data.l2_cache * (m_totalCores / 2) * m_sockets; - m_l2_exclusive = true; + m_L2 = data.l2_cache * (cores() / 2) * m_sockets; + m_L2_exclusive = true; } // Workaround for Intel Pentium Dual-Core, Core Duo, Core 2 Duo, Core 2 Quad and their Xeon homologue // These processors have L2 cache shared by 2 cores. else if (data.vendor == VENDOR_INTEL && data.ext_family == 0x06 && (data.ext_model == 0x0E || data.ext_model == 0x0F || data.ext_model == 0x17)) { - int l2_count_per_socket = m_totalCores > 1 ? m_totalCores / 2 : 1; - m_l2_cache = data.l2_cache > 0 ? data.l2_cache * l2_count_per_socket * m_sockets : 0; + int l2_count_per_socket = cores() > 1 ? cores() / 2 : 1; + m_L2 = data.l2_cache > 0 ? data.l2_cache * l2_count_per_socket * m_sockets : 0; } else{ - m_l2_cache = data.l2_cache > 0 ? data.l2_cache * m_totalCores * m_sockets : 0; + m_L2 = data.l2_cache > 0 ? data.l2_cache * cores() * m_sockets : 0; } -# if defined(__x86_64__) || defined(_M_AMD64) - m_flags |= X86_64; -# endif - - if (data.flags[CPU_FEATURE_AES]) { - m_flags |= AES; - } - - if (data.flags[CPU_FEATURE_BMI2]) { - m_flags |= BMI2; - } + m_aes = data.flags[CPU_FEATURE_AES]; +} + + +size_t xmrig::AdvancedCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const +{ + if (threads() == 1) { + return 1; + } + + size_t cache = 0; + if (m_L3) { + cache = m_L2_exclusive ? (m_L2 + m_L3) : m_L3; + } + else { + cache = m_L2; + } + + size_t count = 0; + + if (cache) { + count = cache / memSize; + + if (cache % memSize >= memSize / 2) { + count++; + } + } + else { + count = threads() / 2; + } + + if (count > (size_t) threads()) { + count = threads(); + } + + if (((float) count / threads() * 100) > maxCpuUsage) { + count = (int) ceil((float) threads() * (maxCpuUsage / 100.0)); + } + + return count < 1 ? 1 : count; } diff --git a/src/core/cpu/AdvancedCpuInfo.h b/src/core/cpu/AdvancedCpuInfo.h new file mode 100644 index 00000000..96fd329a --- /dev/null +++ b/src/core/cpu/AdvancedCpuInfo.h @@ -0,0 +1,75 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2016-2018 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_ADVANCEDCPUINFO_H +#define XMRIG_ADVANCEDCPUINFO_H + + +#include "common/interfaces/ICpuInfo.h" + + +namespace xmrig { + + +class AdvancedCpuInfo : public ICpuInfo +{ +public: + AdvancedCpuInfo(); + +protected: + size_t optimalThreadsCount(size_t memSize, int maxCpuUsage) const override; + + inline Assembly assembly() const override { return ASM_NONE; } + inline bool hasAES() const override { return m_aes; } + inline bool isSupported() const override { return true; } + inline const char *brand() const override { return m_brand; } + inline int32_t cores() const override { return m_cores; } + inline int32_t L2() const override { return m_L2; } + inline int32_t L3() const override { return m_L3; } + inline int32_t nodes() const override { return -1; } + inline int32_t sockets() const override { return m_sockets; } + inline int32_t threads() const override { return m_threads; } + +# if defined(__x86_64__) || defined(_M_AMD64) + inline bool isX64() const override { return true; } +# else + inline bool isX64() const override { return false; } +# endif + +private: + bool m_aes; + bool m_L2_exclusive; + char m_brand[64]; + int32_t m_cores; + int32_t m_L2; + int32_t m_L3; + int32_t m_sockets; + int32_t m_threads; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_ADVANCEDCPUINFO_H */ diff --git a/src/Cpu_win.cpp b/src/core/cpu/Cpu.cpp similarity index 69% rename from src/Cpu_win.cpp rename to src/core/cpu/Cpu.cpp index 7258f726..773255d2 100644 --- a/src/Cpu_win.cpp +++ b/src/core/cpu/Cpu.cpp @@ -22,20 +22,40 @@ */ -#include +#include -#include "Cpu.h" +#include "common/cpu/Cpu.h" -void Cpu::init() +#ifndef XMRIG_NO_LIBCPUID +# include "core/cpu/AdvancedCpuInfo.h" +#endif + + +static xmrig::ICpuInfo *cpuInfo = nullptr; + + +xmrig::ICpuInfo *xmrig::Cpu::info() { -# ifdef XMRIG_NO_LIBCPUID - SYSTEM_INFO sysinfo; - GetSystemInfo(&sysinfo); + assert(cpuInfo != nullptr); - m_totalThreads = sysinfo.dwNumberOfProcessors; -# endif - - initCommon(); + return cpuInfo; +} + + +void xmrig::Cpu::init() +{ + assert(cpuInfo == nullptr); + + cpuInfo = new AdvancedCpuInfo(); +} + + +void xmrig::Cpu::release() +{ + assert(cpuInfo != nullptr); + + delete cpuInfo; + cpuInfo = nullptr; } diff --git a/src/workers/Worker.cpp b/src/workers/Worker.cpp index 567b3e08..c569908c 100644 --- a/src/workers/Worker.cpp +++ b/src/workers/Worker.cpp @@ -24,8 +24,8 @@ #include +#include "common/cpu/Cpu.h" #include "common/Platform.h" -#include "Cpu.h" #include "workers/CpuThread.h" #include "workers/Handle.h" #include "workers/Worker.h" @@ -41,7 +41,7 @@ Worker::Worker(Handle *handle) : m_sequence(0), m_thread(static_cast(handle->config())) { - if (Cpu::threads() > 1 && m_thread->affinity() != -1L) { + if (xmrig::Cpu::info()->threads() > 1 && m_thread->affinity() != -1L) { Platform::setThreadAffinity(m_thread->affinity()); }