Old static class Cpu replaced to interface ICpuInfo.

This commit is contained in:
XMRig 2018-09-23 17:51:56 +03:00
parent 1f609c7ebd
commit ee4d980955
18 changed files with 406 additions and 281 deletions

View file

@ -20,6 +20,7 @@ set(HEADERS
src/common/config/ConfigLoader.h src/common/config/ConfigLoader.h
src/common/config/ConfigWatcher.h src/common/config/ConfigWatcher.h
src/common/Console.h src/common/Console.h
src/common/cpu/Cpu.h
src/common/crypto/Algorithm.h src/common/crypto/Algorithm.h
src/common/crypto/keccak.h src/common/crypto/keccak.h
src/common/interfaces/IClientListener.h src/common/interfaces/IClientListener.h
@ -27,6 +28,7 @@ set(HEADERS
src/common/interfaces/IConfigCreator.h src/common/interfaces/IConfigCreator.h
src/common/interfaces/IConsoleListener.h src/common/interfaces/IConsoleListener.h
src/common/interfaces/IControllerListener.h src/common/interfaces/IControllerListener.h
src/common/interfaces/ICpuInfo.h
src/common/interfaces/ILogBackend.h src/common/interfaces/ILogBackend.h
src/common/interfaces/IStrategy.h src/common/interfaces/IStrategy.h
src/common/interfaces/IStrategyListener.h src/common/interfaces/IStrategyListener.h
@ -49,7 +51,6 @@ set(HEADERS
src/common/xmrig.h src/common/xmrig.h
src/core/ConfigLoader_platform.h src/core/ConfigLoader_platform.h
src/core/Controller.h src/core/Controller.h
src/Cpu.h
src/interfaces/IJobResultListener.h src/interfaces/IJobResultListener.h
src/interfaces/IThread.h src/interfaces/IThread.h
src/interfaces/IWorker.h src/interfaces/IWorker.h
@ -135,7 +136,6 @@ if (WIN32)
res/app.rc res/app.rc
src/App_win.cpp src/App_win.cpp
src/common/Platform_win.cpp src/common/Platform_win.cpp
src/Cpu_win.cpp
src/Mem_win.cpp src/Mem_win.cpp
) )
@ -145,14 +145,12 @@ elseif (APPLE)
set(SOURCES_OS set(SOURCES_OS
src/App_unix.cpp src/App_unix.cpp
src/common/Platform_mac.cpp src/common/Platform_mac.cpp
src/Cpu_mac.cpp
src/Mem_unix.cpp src/Mem_unix.cpp
) )
else() else()
set(SOURCES_OS set(SOURCES_OS
src/App_unix.cpp src/App_unix.cpp
src/common/Platform_unix.cpp src/common/Platform_unix.cpp
src/Cpu_unix.cpp
src/Mem_unix.cpp src/Mem_unix.cpp
) )
@ -184,14 +182,15 @@ if (WITH_LIBCPUID)
include_directories(src/3rdparty/libcpuid) include_directories(src/3rdparty/libcpuid)
set(CPUID_LIB cpuid) 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() else()
add_definitions(/DXMRIG_NO_LIBCPUID) add_definitions(/DXMRIG_NO_LIBCPUID)
set(SOURCES_CPUID src/common/cpu/BasicCpuInfo.h src/common/cpu/Cpu.cpp)
if (XMRIG_ARM) if (XMRIG_ARM)
set(SOURCES_CPUID src/Cpu_arm.cpp) set(SOURCES_CPUID ${SOURCES_CPUID} src/common/cpu/BasicCpuInfo_arm.cpp)
else() else()
set(SOURCES_CPUID src/Cpu_stub.cpp) set(SOURCES_CPUID ${SOURCES_CPUID} src/common/cpu/BasicCpuInfo.cpp)
endif() endif()
endif() endif()

View file

@ -29,11 +29,11 @@
#include "api/Api.h" #include "api/Api.h"
#include "App.h" #include "App.h"
#include "common/Console.h" #include "common/Console.h"
#include "common/cpu/Cpu.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "Cpu.h"
#include "crypto/CryptoNight.h" #include "crypto/CryptoNight.h"
#include "Mem.h" #include "Mem.h"
#include "net/Network.h" #include "net/Network.h"

View file

@ -1,66 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __CPU_H__
#define __CPU_H__
#include <stdint.h>
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__ */

View file

@ -27,11 +27,11 @@
#include <uv.h> #include <uv.h>
#include "common/cpu/Cpu.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "common/net/Pool.h" #include "common/net/Pool.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "Cpu.h"
#include "Mem.h" #include "Mem.h"
#include "Summary.h" #include "Summary.h"
#include "version.h" #include "version.h"
@ -52,21 +52,23 @@ static void print_memory(xmrig::Config *config) {
static void print_cpu(xmrig::Config *config) static void print_cpu(xmrig::Config *config)
{ {
using namespace xmrig;
if (config->isColors()) { if (config->isColors()) {
Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s (%d)") " %sx64 %sAES", Log::i()->text(GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s (%d)") " %sx64 %sAES",
"CPU", "CPU",
Cpu::brand(), Cpu::info()->brand(),
Cpu::sockets(), Cpu::info()->sockets(),
Cpu::isX64() ? "\x1B[1;32m" : "\x1B[1;31m-", Cpu::info()->isX64() ? "\x1B[1;32m" : "\x1B[1;31m-",
Cpu::hasAES() ? "\x1B[1;32m" : "\x1B[1;31m-"); Cpu::info()->hasAES() ? "\x1B[1;32m" : "\x1B[1;31m-");
# ifndef XMRIG_NO_LIBCPUID # 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 # endif
} }
else { 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 # 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 # endif
} }
} }

View file

@ -35,12 +35,12 @@
#include "api/ApiRouter.h" #include "api/ApiRouter.h"
#include "common/api/HttpReply.h" #include "common/api/HttpReply.h"
#include "common/api/HttpRequest.h" #include "common/api/HttpRequest.h"
#include "common/cpu/Cpu.h"
#include "common/crypto/keccak.h" #include "common/crypto/keccak.h"
#include "common/net/Job.h" #include "common/net/Job.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "Cpu.h"
#include "interfaces/IThread.h" #include "interfaces/IThread.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "rapidjson/prettywriter.h" #include "rapidjson/prettywriter.h"
@ -238,13 +238,14 @@ void ApiRouter::getIdentify(rapidjson::Document &doc) const
void ApiRouter::getMiner(rapidjson::Document &doc) const void ApiRouter::getMiner(rapidjson::Document &doc) const
{ {
using namespace xmrig;
auto &allocator = doc.GetAllocator(); auto &allocator = doc.GetAllocator();
rapidjson::Value cpu(rapidjson::kObjectType); rapidjson::Value cpu(rapidjson::kObjectType);
cpu.AddMember("brand", rapidjson::StringRef(Cpu::brand()), allocator); cpu.AddMember("brand", rapidjson::StringRef(Cpu::info()->brand()), allocator);
cpu.AddMember("aes", Cpu::hasAES(), allocator); cpu.AddMember("aes", Cpu::info()->hasAES(), allocator);
cpu.AddMember("x64", Cpu::isX64(), allocator); cpu.AddMember("x64", Cpu::info()->isX64(), allocator);
cpu.AddMember("sockets", Cpu::sockets(), allocator); cpu.AddMember("sockets", Cpu::info()->sockets(), allocator);
doc.AddMember("version", APP_VERSION, allocator); doc.AddMember("version", APP_VERSION, allocator);
doc.AddMember("kind", APP_KIND, allocator); doc.AddMember("kind", APP_KIND, allocator);

View file

@ -21,6 +21,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <string.h>
#include <thread>
#ifdef _MSC_VER #ifdef _MSC_VER
# include <intrin.h> # include <intrin.h>
@ -32,14 +35,8 @@
# define bit_AES (1 << 25) # define bit_AES (1 << 25)
#endif #endif
#ifndef bit_BMI2
# define bit_BMI2 (1 << 8)
#endif
#include <string.h> #include "common/cpu/BasicCpuInfo.h"
#include "Cpu.h"
#define VENDOR_ID (0) #define VENDOR_ID (0)
@ -96,43 +93,18 @@ static inline bool has_aes_ni()
} }
static inline bool has_bmi2() { xmrig::BasicCpuInfo::BasicCpuInfo() :
int cpu_info[4] = { 0 }; m_aes(has_aes_ni()),
cpuid(EXTENDED_FEATURES, cpu_info); m_brand(),
m_threads(std::thread::hardware_concurrency())
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()
{ {
cpu_brand_string(m_brand); cpu_brand_string(m_brand);
}
# if defined(__x86_64__) || defined(_M_AMD64)
m_flags |= X86_64;
# endif size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const
{
if (has_aes_ni()) { const size_t count = threads() / 2;
m_flags |= AES;
} return count < 1 ? 1 : count;
if (has_bmi2()) {
m_flags |= BMI2;
}
} }

View file

@ -0,0 +1,70 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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 */

View file

@ -21,37 +21,27 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <string.h> #include <string.h>
#include <thread>
#include "Cpu.h" #include "common/cpu/BasicCpuInfo.h"
char Cpu::m_brand[64] = { 0 }; xmrig::BasicCpuInfo::BasicCpuInfo() :
int Cpu::m_flags = 0; m_aes(false),
int Cpu::m_l2_cache = 0; m_brand(),
int Cpu::m_l3_cache = 0; m_threads(std::thread::hardware_concurrency())
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()
{ {
memcpy(m_brand, "Unknown", 7); memcpy(m_brand, "Unknown", 7);
# if defined (__arm64__) || defined (__aarch64__)
m_flags |= X86_64;
# endif
# if __ARM_FEATURE_CRYPTO # if __ARM_FEATURE_CRYPTO
m_flags |= AES; m_flags |= AES;
# endif # endif
} }
size_t xmrig::BasicCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const
{
return threads();
}

View file

@ -22,33 +22,36 @@
*/ */
#ifdef __FreeBSD__ #include <assert.h>
# include <sys/types.h>
# include <sys/param.h>
# include <sys/cpuset.h>
# include <pthread_np.h>
#endif
#include <pthread.h> #include "common/cpu/BasicCpuInfo.h"
#include <sched.h> #include "common/cpu/Cpu.h"
#include <unistd.h>
#include <string.h>
#include "Cpu.h" static xmrig::ICpuInfo *cpuInfo = nullptr;
#ifdef __FreeBSD__ xmrig::ICpuInfo *xmrig::Cpu::info()
typedef cpuset_t cpu_set_t;
#endif
void Cpu::init()
{ {
# ifdef XMRIG_NO_LIBCPUID assert(cpuInfo != nullptr);
m_totalThreads = sysconf(_SC_NPROCESSORS_CONF);
# endif
initCommon(); return cpuInfo;
}
void xmrig::Cpu::init()
{
assert(cpuInfo == nullptr);
cpuInfo = new BasicCpuInfo();
}
void xmrig::Cpu::release()
{
assert(cpuInfo != nullptr);
delete cpuInfo;
cpuInfo = nullptr;
} }

View file

@ -4,7 +4,7 @@
* Copyright 2014 Lucas Jones <https://github.com/lucasjones> * Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet> * Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
@ -21,20 +21,26 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef XMRIG_CPU_H
#include <pthread.h> #define XMRIG_CPU_H
#include <sched.h>
#include <unistd.h>
#include "Cpu.h" #include "common/interfaces/ICpuInfo.h"
void Cpu::init() namespace xmrig {
class Cpu
{ {
# ifdef XMRIG_NO_LIBCPUID public:
m_totalThreads = sysconf(_SC_NPROCESSORS_CONF); static ICpuInfo *info();
# endif static void init();
static void release();
};
initCommon();
} } /* namespace xmrig */
#endif /* XMRIG_CPU_H */

View file

@ -0,0 +1,59 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2016-2018 XMRig <support@xmrig.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_CPUINFO_H
#define XMRIG_CPUINFO_H
#include <stdint.h>
#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

View file

@ -94,6 +94,14 @@ enum OclVendor {
}; };
enum Assembly {
ASM_NONE,
ASM_AUTO,
ASM_INTEL,
ASM_RYZEN
};
} /* namespace xmrig */ } /* namespace xmrig */

View file

@ -27,9 +27,9 @@
#include "common/config/ConfigLoader.h" #include "common/config/ConfigLoader.h"
#include "common/cpu/Cpu.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/ConfigCreator.h" #include "core/ConfigCreator.h"
#include "Cpu.h"
#include "crypto/CryptoNight_constants.h" #include "crypto/CryptoNight_constants.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "rapidjson/filewritestream.h" #include "rapidjson/filewritestream.h"
@ -153,7 +153,7 @@ bool xmrig::Config::finalize()
if (!m_threads.cpu.empty()) { if (!m_threads.cpu.empty()) {
m_threads.mode = Advanced; 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) { 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)); 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; const size_t size = CpuThread::multiway(av) * cn_select_memory(m_algorithm.algo()) / 1024;
if (!m_threads.count) { 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) { 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) { if (m_threads.count > count) {
m_threads.count = count; m_threads.count = count;
} }
@ -232,7 +232,7 @@ bool xmrig::Config::parseString(int key, const char *arg)
case ThreadsKey: /* --threads */ case ThreadsKey: /* --threads */
if (strncmp(arg, "all", 3) == 0) { if (strncmp(arg, "all", 3) == 0) {
m_threads.count = Cpu::threads(); m_threads.count = Cpu::info()->threads();
return true; return true;
} }
@ -339,10 +339,10 @@ xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const
# endif # endif
if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) { 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<AlgoVariant>(m_algoVariant + 2); return static_cast<AlgoVariant>(m_algoVariant + 2);
} }
@ -354,10 +354,10 @@ xmrig::AlgoVariant xmrig::Config::getAlgoVariant() const
xmrig::AlgoVariant xmrig::Config::getAlgoVariantLite() const xmrig::AlgoVariant xmrig::Config::getAlgoVariantLite() const
{ {
if (m_algoVariant <= AV_AUTO || m_algoVariant >= AV_MAX) { 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<AlgoVariant>(m_algoVariant + 2); return static_cast<AlgoVariant>(m_algoVariant + 2);
} }

View file

@ -26,6 +26,7 @@
#include "common/config/ConfigLoader.h" #include "common/config/ConfigLoader.h"
#include "common/cpu/Cpu.h"
#include "common/interfaces/IControllerListener.h" #include "common/interfaces/IControllerListener.h"
#include "common/log/ConsoleLog.h" #include "common/log/ConsoleLog.h"
#include "common/log/FileLog.h" #include "common/log/FileLog.h"
@ -33,7 +34,6 @@
#include "common/Platform.h" #include "common/Platform.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "Cpu.h"
#include "net/Network.h" #include "net/Network.h"

View file

@ -21,65 +21,24 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <libcpuid.h> #include <libcpuid.h>
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include <thread>
#include "Cpu.h" #include "core/cpu/AdvancedCpuInfo.h"
bool Cpu::m_l2_exclusive = false; xmrig::AdvancedCpuInfo::AdvancedCpuInfo() :
char Cpu::m_brand[64] = { 0 }; m_aes(false),
int Cpu::m_flags = 0; m_L2_exclusive(false),
int Cpu::m_l2_cache = 0; m_brand(),
int Cpu::m_l3_cache = 0; m_cores(0),
int Cpu::m_sockets = 1; m_L2(0),
int Cpu::m_totalCores = 0; m_L3(0),
size_t Cpu::m_totalThreads = 0; m_sockets(1),
m_threads(std::thread::hardware_concurrency())
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()
{ {
struct cpu_raw_data_t raw = { 0 }; struct cpu_raw_data_t raw = { 0 };
struct cpu_id_t data = { 0 }; struct cpu_id_t data = { 0 };
@ -89,40 +48,67 @@ void Cpu::initCommon()
strncpy(m_brand, data.brand_str, sizeof(m_brand) - 1); strncpy(m_brand, data.brand_str, sizeof(m_brand) - 1);
m_totalThreads = data.total_logical_cpus; m_sockets = threads() / data.num_logical_cpus;
m_sockets = m_totalThreads / data.num_logical_cpus;
if (m_sockets == 0) { if (m_sockets == 0) {
m_sockets = 1; m_sockets = 1;
} }
m_totalCores = data.num_cores * m_sockets; m_cores = data.num_cores * m_sockets;
m_l3_cache = data.l3_cache > 0 ? data.l3_cache * m_sockets : 0; m_L3 = data.l3_cache > 0 ? data.l3_cache * m_sockets : 0;
// Workaround for AMD CPUs https://github.com/anrieff/libcpuid/issues/97 // Workaround for AMD CPUs https://github.com/anrieff/libcpuid/issues/97
if (data.vendor == VENDOR_AMD && data.ext_family >= 0x15 && data.ext_family < 0x17) { 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 = data.l2_cache * (cores() / 2) * m_sockets;
m_l2_exclusive = true; m_L2_exclusive = true;
} }
// Workaround for Intel Pentium Dual-Core, Core Duo, Core 2 Duo, Core 2 Quad and their Xeon homologue // 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. // 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)) { 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; int l2_count_per_socket = cores() > 1 ? cores() / 2 : 1;
m_l2_cache = data.l2_cache > 0 ? data.l2_cache * l2_count_per_socket * m_sockets : 0; m_L2 = data.l2_cache > 0 ? data.l2_cache * l2_count_per_socket * m_sockets : 0;
} }
else{ 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_aes = data.flags[CPU_FEATURE_AES];
m_flags |= X86_64; }
# endif
if (data.flags[CPU_FEATURE_AES]) { size_t xmrig::AdvancedCpuInfo::optimalThreadsCount(size_t memSize, int maxCpuUsage) const
m_flags |= AES; {
} if (threads() == 1) {
return 1;
if (data.flags[CPU_FEATURE_BMI2]) { }
m_flags |= BMI2;
} 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;
} }

View file

@ -0,0 +1,75 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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 */

View file

@ -22,20 +22,40 @@
*/ */
#include <windows.h> #include <assert.h>
#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 assert(cpuInfo != nullptr);
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
m_totalThreads = sysinfo.dwNumberOfProcessors; return cpuInfo;
# endif }
initCommon();
void xmrig::Cpu::init()
{
assert(cpuInfo == nullptr);
cpuInfo = new AdvancedCpuInfo();
}
void xmrig::Cpu::release()
{
assert(cpuInfo != nullptr);
delete cpuInfo;
cpuInfo = nullptr;
} }

View file

@ -24,8 +24,8 @@
#include <chrono> #include <chrono>
#include "common/cpu/Cpu.h"
#include "common/Platform.h" #include "common/Platform.h"
#include "Cpu.h"
#include "workers/CpuThread.h" #include "workers/CpuThread.h"
#include "workers/Handle.h" #include "workers/Handle.h"
#include "workers/Worker.h" #include "workers/Worker.h"
@ -41,7 +41,7 @@ Worker::Worker(Handle *handle) :
m_sequence(0), m_sequence(0),
m_thread(static_cast<xmrig::CpuThread *>(handle->config())) m_thread(static_cast<xmrig::CpuThread *>(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()); Platform::setThreadAffinity(m_thread->affinity());
} }