Add Cpu class.

This commit is contained in:
XMRig 2017-06-08 00:10:26 +03:00
parent 1cf5ad5212
commit 0556fd664c
8 changed files with 119 additions and 210 deletions

View file

@ -1,6 +1,9 @@
cmake_minimum_required(VERSION 3.0)
project(xmrig)
option(WITH_LIBCPUID "Use Libcpuid" ON)
option(WITH_AEON "CryptoNight-Lite support" ON)
set(HEADERS
src/App.h
src/interfaces/IClientListener.h
@ -10,6 +13,7 @@ set(HEADERS
src/net/Url.h
src/Options.h
src/Console.h
src/Cpu.h
src/version.h
)
@ -29,12 +33,13 @@ if (WIN32)
res/app.rc
src/3rdparty/winansi.cpp
src/3rdparty/winansi.h
src/Cpu_win.cpp
src/net/Network_win.cpp
)
set(EXTRA_LIBS ws2_32 psapi iphlpapi userenv)
else()
set(SOURCES_OS unix/cpu_unix.c unix/memory_unix.c unix/xmrig_unix.c)
set(SOURCES_OS src/Cpu_unix.cpp)
set(EXTRA_LIBS pthread)
endif()
@ -60,6 +65,17 @@ if (WIN32)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
endif()
if (WITH_LIBCPUID)
# add_subdirectory(compat/libcpuid)
# include_directories(compat/libcpuid)
# set(CPUID_LIB cpuid)
# set(SOURCES_CPUID cpu.c)
else()
add_definitions(/DXMRIG_NO_LIBCPUID)
set(SOURCES_CPUID src/Cpu_stub.cpp)
endif()
include_directories(src)
include_directories(src/3rdparty)
include_directories(src/3rdparty/jansson)
@ -67,5 +83,5 @@ include_directories(${UV_INCLUDE_DIR})
add_subdirectory(src/3rdparty/jansson)
add_executable(xmrig ${HEADERS} ${SOURCES} ${SOURCES_OS})
add_executable(xmrig ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID})
target_link_libraries(xmrig jansson ${UV_LIBRARIES} ${EXTRA_LIBS})

100
cpu.c
View file

@ -1,100 +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 2016-2017 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/>.
*/
#include <cpuid.h>
#include <string.h>
#include <stdbool.h>
#include <math.h>
#ifndef BUILD_TEST
# include <libcpuid.h>
#endif
#include "cpu.h"
#ifndef BUILD_TEST
void cpu_init_common() {
struct cpu_raw_data_t raw = { 0 };
struct cpu_id_t data = { 0 };
cpuid_get_raw_data(&raw);
cpu_identify(&raw, &data);
strncpy(cpu_info.brand, data.brand_str, sizeof(cpu_info.brand) - 1);
cpu_info.total_logical_cpus = data.total_logical_cpus;
cpu_info.sockets = data.total_logical_cpus / data.num_logical_cpus;
cpu_info.total_cores = data.num_cores * cpu_info.sockets;
cpu_info.l3_cache = data.l3_cache > 0 ? data.l3_cache * cpu_info.sockets : 0;
// Workaround for AMD CPUs https://github.com/anrieff/libcpuid/issues/97
if (data.vendor == VENDOR_AMD && data.l3_cache <= 0 && data.l2_assoc == 16 && data.ext_family >= 21) {
cpu_info.l2_cache = data.l2_cache * (cpu_info.total_cores / 2) * cpu_info.sockets;
}
else {
cpu_info.l2_cache = data.l2_cache > 0 ? data.l2_cache * cpu_info.total_cores * cpu_info.sockets : 0;
}
# ifdef __x86_64__
cpu_info.flags |= CPU_FLAG_X86_64;
# endif
if (data.flags[CPU_FEATURE_AES]) {
cpu_info.flags |= CPU_FLAG_AES;
}
if (data.flags[CPU_FEATURE_BMI2]) {
cpu_info.flags |= CPU_FLAG_BMI2;
}
}
#endif
int get_optimal_threads_count(int algo, bool double_hash, int max_cpu_usage) {
if (cpu_info.total_logical_cpus == 1) {
return 1;
}
int cache = cpu_info.l3_cache ? cpu_info.l3_cache : cpu_info.l2_cache;
int count = 0;
const int size = (algo ? 1024 : 2048) * (double_hash ? 2 : 1);
if (cache) {
count = cache / size;
}
else {
count = cpu_info.total_logical_cpus / 2;
}
if (count > cpu_info.total_logical_cpus) {
count = cpu_info.total_logical_cpus;
}
if (((float) count / cpu_info.total_logical_cpus * 100) > max_cpu_usage) {
count = ceil((float) cpu_info.total_logical_cpus * (max_cpu_usage / 100.0));
}
return count < 1 ? 1 : count;
}

View file

@ -27,26 +27,19 @@
#include "App.h"
#include "Console.h"
#include "Cpu.h"
#include "net/Client.h"
#include "net/Network.h"
#include "Options.h"
#include "version.h"
Client *client;
uv_timer_t timer_req;
void timer_cb(uv_timer_t* handle) {
LOG_DEBUG("TIMER");
client->disconnect();
}
App::App(int argc, char **argv)
{
Console::init();
Cpu::init();
m_options = Options::parse(argc, argv);
m_network = new Network(m_options);
}
@ -69,13 +62,6 @@ App::exec()
m_network->connect();
// uv_timer_init(uv_default_loop(), &timer_req);
// uv_timer_start(&timer_req, timer_cb, 5000, 5000);
// client = new Client();
// client->connect("192.168.2.34", 3333);
const int r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
uv_loop_close(uv_default_loop());

View file

@ -21,33 +21,4 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CPU_H__
#define __CPU_H__
#include <stdbool.h>
struct cpu_info {
int total_cores;
int total_logical_cpus;
int flags;
int sockets;
int l2_cache;
int l3_cache;
char brand[64];
};
extern struct cpu_info cpu_info;
enum cpu_flags {
CPU_FLAG_X86_64 = 1,
CPU_FLAG_AES = 2,
CPU_FLAG_BMI2 = 4
};
void cpu_init();
int get_optimal_threads_count(int algo, bool double_hash, int max_cpu_usage);
int affine_to_cpu_mask(int id, unsigned long mask);
#endif /* __CPU_H__ */

62
src/Cpu.h Normal file
View file

@ -0,0 +1,62 @@
/* 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-2017 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__
class Cpu
{
public:
enum Flags {
X86_64 = 1,
AES = 2,
BMI2 = 4
};
static int optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage);
static void init();
static void setAffinity(int id, unsigned long mask);
static inline bool hasAES() { return m_flags & AES; }
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 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 int m_totalThreads;
};
#endif /* __CPU_H__ */

View file

@ -21,10 +21,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <cpuid.h>
#include <string.h>
#include <stdbool.h>
#include "cpu.h"
#include "Cpu.h"
#define VENDOR_ID (0)
@ -52,7 +54,7 @@ static inline void cpuid(int level, int output[4]) {
}
static void cpu_brand_string(char* s) {
static inline void cpu_brand_string(char* s) {
int cpu_info[4] = { 0 };
cpuid(VENDOR_ID, cpu_info);
@ -66,7 +68,7 @@ static void cpu_brand_string(char* s) {
}
static bool has_aes_ni()
static inline bool has_aes_ni()
{
int cpu_info[4] = { 0 };
cpuid(PROCESSOR_INFO, cpu_info);
@ -75,7 +77,7 @@ static bool has_aes_ni()
}
static bool has_bmi2() {
static inline bool has_bmi2() {
int cpu_info[4] = { 0 };
cpuid(EXTENDED_FEATURES, cpu_info);
@ -83,25 +85,35 @@ static bool has_bmi2() {
}
void cpu_init_common() {
cpu_info.sockets = 1;
cpu_brand_string(cpu_info.brand);
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;
int Cpu::m_totalThreads = 0;
int Cpu::optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage)
{
int count = m_totalThreads / 2;
return count < 1 ? 1 : count;
}
void Cpu::initCommon()
{
cpu_brand_string(m_brand);
# ifdef __x86_64__
cpu_info.flags |= CPU_FLAG_X86_64;
m_flags |= X86_64;
# endif
if (has_aes_ni()) {
cpu_info.flags |= CPU_FLAG_AES;
m_flags |= AES;
}
if (has_bmi2()) {
cpu_info.flags |= CPU_FLAG_BMI2;
m_flags |= BMI2;
}
}
int get_optimal_threads_count(int algo, bool double_hash, int max_cpu_usage) {
int count = cpu_info.total_logical_cpus / 2;
return count < 1 ? 1 : count;
}

View file

@ -21,40 +21,4 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <unistd.h>
#include <sched.h>
#include <pthread.h>
#include "cpu.h"
struct cpu_info cpu_info = { 0 };
void cpu_init_common();
void cpu_init() {
# ifdef XMRIG_NO_LIBCPUID
cpu_info.total_logical_cpus = sysconf(_SC_NPROCESSORS_CONF);
# endif
cpu_init_common();
}
int affine_to_cpu_mask(int id, unsigned long mask)
{
cpu_set_t set;
CPU_ZERO(&set);
for (unsigned i = 0; i < cpu_info.total_logical_cpus; i++) {
if (mask & (1UL << i)) {
CPU_SET(i, &set);
}
}
if (id == -1) {
sched_setaffinity(0, sizeof(&set), &set);
} else {
pthread_setaffinity_np(pthread_self(), sizeof(&set), &set);
}
}

View file

@ -21,29 +21,27 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <windows.h>
#include <stdbool.h>
#include "cpu.h"
struct cpu_info cpu_info = { 0 };
void cpu_init_common();
#include "Cpu.h"
void cpu_init() {
void Cpu::init()
{
# ifdef XMRIG_NO_LIBCPUID
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
cpu_info.total_logical_cpus = sysinfo.dwNumberOfProcessors;
m_totalThreads = sysinfo.dwNumberOfProcessors;
# endif
cpu_init_common();
initCommon();
}
int affine_to_cpu_mask(int id, unsigned long mask)
void Cpu::setAffinity(int id, unsigned long mask)
{
if (id == -1) {
SetProcessAffinityMask(GetCurrentProcess(), mask);