diff --git a/CMakeLists.txt b/CMakeLists.txt index dcc4f728..53b734d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,6 @@ set(SOURCES algo/cryptonight/cryptonight_av5_softaes_double.c util.c options.c - cpu.c stratum.c stats.c memory.c @@ -109,13 +108,15 @@ if (WITH_LIBCPUID) link_directories(${CPUID_LIBRARIES}) set(CPUID_LIB cpuid) + set(SOURCES_CPUID cpu.c) else() add_definitions(/DXMRIG_NO_LIBCPUID) + set(SOURCES_CPUID cpu_stub.c) endif() if (CMAKE_SIZEOF_VOID_P EQUAL 8) add_subdirectory(algo/cryptonight/bmi2) - add_executable(xmrig ${HEADERS} ${HEADERS_CRYPTO} ${SOURCES} ${SOURCES_CRYPTO} ${HEADERS_UTILS} ${SOURCES_UTILS} ${HEADERS_COMPAT} ${SOURCES_COMPAT} ${SOURCES_OS}) + add_executable(xmrig ${HEADERS} ${HEADERS_CRYPTO} ${SOURCES} ${SOURCES_CRYPTO} ${HEADERS_UTILS} ${SOURCES_UTILS} ${HEADERS_COMPAT} ${SOURCES_COMPAT} ${SOURCES_OS} ${SOURCES_CPUID}) target_link_libraries(xmrig jansson curl cryptonight_av3_aesni_bmi2 ${CPUID_LIB} ${EXTRA_LIBS}) else() set(CRYPTONIGHT32 diff --git a/cpu.c b/cpu.c index bfbcee70..655d170d 100644 --- a/cpu.c +++ b/cpu.c @@ -24,77 +24,54 @@ #include #include #include +#include + #include "cpu.h" -#define VENDOR_ID (0) -#define PROCESSOR_INFO (1) -#define CACHE_TLB_DESCRIPTOR (2) -#define EXTENDED_FEATURES (7) -#define PROCESSOR_BRAND_STRING_1 (0x80000002) -#define PROCESSOR_BRAND_STRING_2 (0x80000003) -#define PROCESSOR_BRAND_STRING_3 (0x80000004) - -#define EAX_Reg (0) -#define EBX_Reg (1) -#define ECX_Reg (2) -#define EDX_Reg (3) - - -static inline void cpuid(int level, int output[4]) { - int a, b, c, d; - __cpuid_count(level, 0, a, b, c, d); - - output[0] = a; - output[1] = b; - output[2] = c; - output[3] = d; -} - - -static void cpu_brand_string(char* s) { - int cpu_info[4] = { 0 }; - cpuid(VENDOR_ID, cpu_info); - - if (cpu_info[EAX_Reg] >= 4) { - for (int i = 0; i < 4; i++) { - cpuid(0x80000002 + i, cpu_info); - memcpy(s, cpu_info, sizeof(cpu_info)); - s += 16; - } - } -} - - -static bool has_aes_ni() -{ - int cpu_info[4] = { 0 }; - cpuid(PROCESSOR_INFO, cpu_info); - - return cpu_info[ECX_Reg] & bit_AES; -} - - -static bool has_bmi2() { - int cpu_info[4] = { 0 }; - cpuid(EXTENDED_FEATURES, cpu_info); - - return cpu_info[EBX_Reg] & bit_BMI2; -} - - void cpu_init_common() { - cpu_brand_string(cpu_info.brand); + 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.l2_cache = data.l2_cache > 0 ? data.l2_cache * cpu_info.sockets : 0; + cpu_info.l3_cache = data.l3_cache > 0 ? data.l3_cache * cpu_info.sockets : 0; # ifdef __x86_64__ cpu_info.flags |= CPU_FLAG_X86_64; # endif - if (has_aes_ni()) { + if (data.flags[CPU_FEATURE_AES]) { cpu_info.flags |= CPU_FLAG_AES; } - if (has_bmi2()) { + if (data.flags[CPU_FEATURE_BMI2]) { cpu_info.flags |= CPU_FLAG_BMI2; } } + + +int get_optimal_threads_count() { + int cache = cpu_info.l3_cache ? cpu_info.l3_cache : cpu_info.l2_cache; + int count = 0; + + if (cache) { + count = cache / 2048; + } + else { + count = cpu_info.total_logical_cpus / 2; + } + + if (count > cpu_info.total_logical_cpus) { + return cpu_info.total_logical_cpus; + } + + return count < 1 ? 1 : count; +} diff --git a/cpu.h b/cpu.h index 7c588a9f..df0e79d9 100644 --- a/cpu.h +++ b/cpu.h @@ -25,9 +25,13 @@ #define __CPU_H__ struct cpu_info { - int count; + int total_cores; + int total_logical_cpus; int flags; - char brand[48]; + int sockets; + int l2_cache; + int l3_cache; + char brand[64]; }; extern struct cpu_info cpu_info; @@ -40,7 +44,6 @@ enum cpu_flags { }; - void cpu_init(); int get_optimal_threads_count(); int affine_to_cpu_mask(int id, unsigned long mask); diff --git a/cpu_stub.c b/cpu_stub.c new file mode 100644 index 00000000..243316a1 --- /dev/null +++ b/cpu_stub.c @@ -0,0 +1,107 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2016-2017 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 . + */ + +#include +#include +#include +#include "cpu.h" + + +#define VENDOR_ID (0) +#define PROCESSOR_INFO (1) +#define CACHE_TLB_DESCRIPTOR (2) +#define EXTENDED_FEATURES (7) +#define PROCESSOR_BRAND_STRING_1 (0x80000002) +#define PROCESSOR_BRAND_STRING_2 (0x80000003) +#define PROCESSOR_BRAND_STRING_3 (0x80000004) + +#define EAX_Reg (0) +#define EBX_Reg (1) +#define ECX_Reg (2) +#define EDX_Reg (3) + + +static inline void cpuid(int level, int output[4]) { + int a, b, c, d; + __cpuid_count(level, 0, a, b, c, d); + + output[0] = a; + output[1] = b; + output[2] = c; + output[3] = d; +} + + +static void cpu_brand_string(char* s) { + int cpu_info[4] = { 0 }; + cpuid(VENDOR_ID, cpu_info); + + if (cpu_info[EAX_Reg] >= 4) { + for (int i = 0; i < 4; i++) { + cpuid(0x80000002 + i, cpu_info); + memcpy(s, cpu_info, sizeof(cpu_info)); + s += 16; + } + } +} + + +static bool has_aes_ni() +{ + int cpu_info[4] = { 0 }; + cpuid(PROCESSOR_INFO, cpu_info); + + return cpu_info[ECX_Reg] & bit_AES; +} + + +static bool has_bmi2() { + int cpu_info[4] = { 0 }; + cpuid(EXTENDED_FEATURES, cpu_info); + + return cpu_info[EBX_Reg] & bit_BMI2; +} + + +void cpu_init_common() { + cpu_info.sockets = 1; + cpu_brand_string(cpu_info.brand); + +# ifdef __x86_64__ + cpu_info.flags |= CPU_FLAG_X86_64; +# endif + + if (has_aes_ni()) { + cpu_info.flags |= CPU_FLAG_AES; + } + + if (has_bmi2()) { + cpu_info.flags |= CPU_FLAG_BMI2; + } +} + + +int get_optimal_threads_count() { + int count = cpu_info.total_logical_cpus / 2; + return count < 1 ? 1 : count; +} diff --git a/options.c b/options.c index 7f3de28f..59f8f6da 100644 --- a/options.c +++ b/options.c @@ -244,7 +244,7 @@ static void parse_arg(int key, char *arg) { case 1020: /* --cpu-affinity */ p = strstr(arg, "0x"); ul = p ? strtoul(p, NULL, 16) : atol(arg); - if (ul > (1UL << cpu_info.count) -1) { + if (ul > (1UL << cpu_info.total_logical_cpus) -1) { ul = -1; } diff --git a/unix/cpu_unix.c b/unix/cpu_unix.c index b8212f92..0e2f3d44 100644 --- a/unix/cpu_unix.c +++ b/unix/cpu_unix.c @@ -33,18 +33,14 @@ void cpu_init_common(); void cpu_init() { - cpu_info.count = sysconf(_SC_NPROCESSORS_CONF); +# ifdef XMRIG_NO_LIBCPUID + cpu_info.total_logical_cpus = sysconf(_SC_NPROCESSORS_CONF); +# endif cpu_init_common(); } -int get_optimal_threads_count() { - int count = cpu_info.count / 2; - return count < 1 ? 1 : count; -} - - int affine_to_cpu_mask(int id, unsigned long mask) { cpu_set_t set; diff --git a/utils/summary.c b/utils/summary.c index d70dcb83..3211bc09 100644 --- a/utils/summary.c +++ b/utils/summary.c @@ -44,15 +44,28 @@ static void print_memory() { static void print_cpu() { const char *t1 = (cpu_info.flags & CPU_FLAG_X86_64) ? OPT_COLOR(CL_LGR, "x86_64") : OPT_COLOR(CL_LRD, "-x86_64"); const char *t2 = (cpu_info.flags & CPU_FLAG_AES) ? OPT_COLOR(CL_LGR, "AES-NI") : OPT_COLOR(CL_LRD, "-AES-NI"); - const char *t3 = (cpu_info.flags & CPU_FLAG_BMI2) ? OPT_COLOR(CL_LGR, "BMI2") : OPT_COLOR(CL_LRD, "-BMI2"); if (opt_colors) { - applog_notime(LOG_INFO, CL_LGR " * " CL_WHT "CPU: %s", cpu_info.brand); - applog_notime(LOG_INFO, CL_LGR " * " CL_WHT "CPU FEATURES: %s %s %s", t1, t2, t3); + applog_notime(LOG_INFO, CL_LGR " * " CL_WHT "CPU: %s (%d)", cpu_info.brand, cpu_info.sockets); } else { - applog_notime(LOG_INFO, " * CPU: %s", cpu_info.brand); - applog_notime(LOG_INFO, " * CPU FEATURES: %s %s %s", t1, t2, t3); + applog_notime(LOG_INFO, " * CPU: %s (%d)", cpu_info.brand, cpu_info.sockets); + } + + # ifndef XMRIG_NO_LIBCPUID + if (opt_colors) { + applog_notime(LOG_INFO, CL_LGR " * " CL_WHT "CPU L2/L3: %dK/%dK", cpu_info.l2_cache, cpu_info.l3_cache); + } + else { + applog_notime(LOG_INFO, " * CPU L2/L3: %dK/%dK", cpu_info.l2_cache, cpu_info.l3_cache); + } + # endif + + if (opt_colors) { + applog_notime(LOG_INFO, CL_LGR " * " CL_WHT "CPU FEATURES: %s %s", t1, t2); + } + else { + applog_notime(LOG_INFO, " * CPU FEATURES: %s %s", t1, t2); } } diff --git a/win/cpu_win.c b/win/cpu_win.c index b03fa43b..6b5cc7fa 100644 --- a/win/cpu_win.c +++ b/win/cpu_win.c @@ -20,7 +20,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - + #include #include @@ -32,21 +32,17 @@ void cpu_init_common(); void cpu_init() { +# ifdef XMRIG_NO_LIBCPUID SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); - cpu_info.count = sysinfo.dwNumberOfProcessors; + cpu_info.total_logical_cpus = sysinfo.dwNumberOfProcessors; +# endif cpu_init_common(); } -int get_optimal_threads_count(int mining_algo) { - int count = cpu_info.count / 2; - return count < 1 ? 1 : count; -} - - int affine_to_cpu_mask(int id, unsigned long mask) { if (id == -1) { diff --git a/xmrig.c b/xmrig.c index 13d19b6d..6d938c77 100644 --- a/xmrig.c +++ b/xmrig.c @@ -262,7 +262,7 @@ static void *miner_thread(void *userdata) { struct cryptonight_ctx *persistentctx = (struct cryptonight_ctx *) create_persistent_ctx(thr_id); - if (cpu_info.count > 1 && opt_affinity != -1L) { + if (cpu_info.total_logical_cpus > 1 && opt_affinity != -1L) { affine_to_cpu_mask(thr_id, (unsigned long) opt_affinity); } @@ -330,7 +330,7 @@ static void *miner_thread_double(void *userdata) { struct cryptonight_ctx *persistentctx = (struct cryptonight_ctx *) create_persistent_ctx(thr_id); - if (cpu_info.count > 1 && opt_affinity != -1L) { + if (cpu_info.total_logical_cpus > 1 && opt_affinity != -1L) { affine_to_cpu_mask(thr_id, (unsigned long) opt_affinity); }