From b11f95d2481d68b777605c096c1a46db7bd70b71 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 8 Jun 2017 01:51:24 +0300 Subject: [PATCH] Restore libcpuid support. --- CMakeLists.txt | 10 +- .../3rdparty}/libcpuid/CMakeLists.txt | 14 +- .../3rdparty}/libcpuid/amd_code_t.h | 0 {compat => src/3rdparty}/libcpuid/asm-bits.c | 0 {compat => src/3rdparty}/libcpuid/asm-bits.h | 0 .../3rdparty}/libcpuid/cpuid_main.c | 337 +++++++++++++++++- .../3rdparty}/libcpuid/intel_code_t.h | 0 {compat => src/3rdparty}/libcpuid/libcpuid.h | 0 .../3rdparty}/libcpuid/libcpuid_constants.h | 0 .../3rdparty}/libcpuid/libcpuid_internal.h | 42 +++ .../3rdparty}/libcpuid/libcpuid_types.h | 0 .../3rdparty}/libcpuid/libcpuid_util.c | 0 .../3rdparty}/libcpuid/libcpuid_util.h | 2 - {compat => src/3rdparty}/libcpuid/recog_amd.c | 23 +- {compat => src/3rdparty}/libcpuid/recog_amd.h | 0 .../3rdparty}/libcpuid/recog_intel.c | 25 +- .../3rdparty}/libcpuid/recog_intel.h | 0 src/Cpu.cpp | 81 +++++ src/Summary.cpp | 3 +- 19 files changed, 478 insertions(+), 59 deletions(-) rename {compat => src/3rdparty}/libcpuid/CMakeLists.txt (68%) rename {compat => src/3rdparty}/libcpuid/amd_code_t.h (100%) rename {compat => src/3rdparty}/libcpuid/asm-bits.c (100%) rename {compat => src/3rdparty}/libcpuid/asm-bits.h (100%) rename {compat => src/3rdparty}/libcpuid/cpuid_main.c (55%) rename {compat => src/3rdparty}/libcpuid/intel_code_t.h (100%) rename {compat => src/3rdparty}/libcpuid/libcpuid.h (100%) rename {compat => src/3rdparty}/libcpuid/libcpuid_constants.h (100%) rename {compat => src/3rdparty}/libcpuid/libcpuid_internal.h (66%) rename {compat => src/3rdparty}/libcpuid/libcpuid_types.h (100%) rename {compat => src/3rdparty}/libcpuid/libcpuid_util.c (100%) rename {compat => src/3rdparty}/libcpuid/libcpuid_util.h (98%) rename {compat => src/3rdparty}/libcpuid/recog_amd.c (98%) rename {compat => src/3rdparty}/libcpuid/recog_amd.h (100%) rename {compat => src/3rdparty}/libcpuid/recog_intel.c (98%) rename {compat => src/3rdparty}/libcpuid/recog_intel.h (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 66200623..11a6d1bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,11 +68,11 @@ if (WIN32) endif() if (WITH_LIBCPUID) -# add_subdirectory(compat/libcpuid) + add_subdirectory(src/3rdparty/libcpuid) -# include_directories(compat/libcpuid) -# set(CPUID_LIB cpuid) -# set(SOURCES_CPUID cpu.c) + include_directories(src/3rdparty/libcpuid) + set(CPUID_LIB cpuid) + set(SOURCES_CPUID src/Cpu.cpp) else() add_definitions(/DXMRIG_NO_LIBCPUID) set(SOURCES_CPUID src/Cpu_stub.cpp) @@ -86,4 +86,4 @@ include_directories(${UV_INCLUDE_DIR}) add_subdirectory(src/3rdparty/jansson) add_executable(xmrig ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID}) -target_link_libraries(xmrig jansson ${UV_LIBRARIES} ${EXTRA_LIBS}) +target_link_libraries(xmrig jansson ${UV_LIBRARIES} ${EXTRA_LIBS} ${CPUID_LIB}) diff --git a/compat/libcpuid/CMakeLists.txt b/src/3rdparty/libcpuid/CMakeLists.txt similarity index 68% rename from compat/libcpuid/CMakeLists.txt rename to src/3rdparty/libcpuid/CMakeLists.txt index 5c37492a..ef541cc3 100644 --- a/compat/libcpuid/CMakeLists.txt +++ b/src/3rdparty/libcpuid/CMakeLists.txt @@ -3,17 +3,19 @@ project (cpuid C) add_definitions(/DVERSION="0.4.0") +set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Os") + set(HEADERS libcpuid.h libcpuid_types.h libcpuid_constants.h libcpuid_internal.h -amd_code_t.h -intel_code_t.h -recog_amd.h -recog_intel.h -asm-bits.h -libcpuid_util.h + amd_code_t.h + intel_code_t.h + recog_amd.h + recog_intel.h + asm-bits.h + libcpuid_util.h ) set(SOURCES diff --git a/compat/libcpuid/amd_code_t.h b/src/3rdparty/libcpuid/amd_code_t.h similarity index 100% rename from compat/libcpuid/amd_code_t.h rename to src/3rdparty/libcpuid/amd_code_t.h diff --git a/compat/libcpuid/asm-bits.c b/src/3rdparty/libcpuid/asm-bits.c similarity index 100% rename from compat/libcpuid/asm-bits.c rename to src/3rdparty/libcpuid/asm-bits.c diff --git a/compat/libcpuid/asm-bits.h b/src/3rdparty/libcpuid/asm-bits.h similarity index 100% rename from compat/libcpuid/asm-bits.h rename to src/3rdparty/libcpuid/asm-bits.h diff --git a/compat/libcpuid/cpuid_main.c b/src/3rdparty/libcpuid/cpuid_main.c similarity index 55% rename from compat/libcpuid/cpuid_main.c rename to src/3rdparty/libcpuid/cpuid_main.c index 64c4198b..504c0af8 100644 --- a/compat/libcpuid/cpuid_main.c +++ b/src/3rdparty/libcpuid/cpuid_main.c @@ -117,7 +117,7 @@ static int get_total_cpus(void) #if defined linux || defined __linux__ || defined __sun #include #include - + static int get_total_cpus(void) { return sysconf(_SC_NPROCESSORS_ONLN); @@ -302,7 +302,7 @@ static int cpuid_basic_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* dat data->ext_model = data->model + (xmodel << 4); } ext = raw->ext_cpuid[0][0] - 0x8000000; - + /* obtain the brand string, if present: */ if (ext >= 4) { for (i = 0; i < 3; i++) @@ -401,6 +401,107 @@ int cpuid_get_raw_data(struct cpu_raw_data_t* data) return set_error(ERR_OK); } +int cpuid_serialize_raw_data(struct cpu_raw_data_t* data, const char* filename) +{ + int i; + FILE *f; + + if (!strcmp(filename, "")) + f = stdout; + else + f = fopen(filename, "wt"); + if (!f) return set_error(ERR_OPEN); + + fprintf(f, "version=%s\n", VERSION); + for (i = 0; i < MAX_CPUID_LEVEL; i++) + fprintf(f, "basic_cpuid[%d]=%08x %08x %08x %08x\n", i, + data->basic_cpuid[i][0], data->basic_cpuid[i][1], + data->basic_cpuid[i][2], data->basic_cpuid[i][3]); + for (i = 0; i < MAX_EXT_CPUID_LEVEL; i++) + fprintf(f, "ext_cpuid[%d]=%08x %08x %08x %08x\n", i, + data->ext_cpuid[i][0], data->ext_cpuid[i][1], + data->ext_cpuid[i][2], data->ext_cpuid[i][3]); + for (i = 0; i < MAX_INTELFN4_LEVEL; i++) + fprintf(f, "intel_fn4[%d]=%08x %08x %08x %08x\n", i, + data->intel_fn4[i][0], data->intel_fn4[i][1], + data->intel_fn4[i][2], data->intel_fn4[i][3]); + for (i = 0; i < MAX_INTELFN11_LEVEL; i++) + fprintf(f, "intel_fn11[%d]=%08x %08x %08x %08x\n", i, + data->intel_fn11[i][0], data->intel_fn11[i][1], + data->intel_fn11[i][2], data->intel_fn11[i][3]); + for (i = 0; i < MAX_INTELFN12H_LEVEL; i++) + fprintf(f, "intel_fn12h[%d]=%08x %08x %08x %08x\n", i, + data->intel_fn12h[i][0], data->intel_fn12h[i][1], + data->intel_fn12h[i][2], data->intel_fn12h[i][3]); + for (i = 0; i < MAX_INTELFN14H_LEVEL; i++) + fprintf(f, "intel_fn14h[%d]=%08x %08x %08x %08x\n", i, + data->intel_fn14h[i][0], data->intel_fn14h[i][1], + data->intel_fn14h[i][2], data->intel_fn14h[i][3]); + + if (strcmp(filename, "")) + fclose(f); + return set_error(ERR_OK); +} + +int cpuid_deserialize_raw_data(struct cpu_raw_data_t* data, const char* filename) +{ + int i, len; + char line[100]; + char token[100]; + char *value; + int syntax; + int cur_line = 0; + int recognized; + FILE *f; + + raw_data_t_constructor(data); + + if (!strcmp(filename, "")) + f = stdin; + else + f = fopen(filename, "rt"); + if (!f) return set_error(ERR_OPEN); + while (fgets(line, sizeof(line), f)) { + ++cur_line; + len = (int) strlen(line); + if (len < 2) continue; + if (line[len - 1] == '\n') + line[--len] = '\0'; + for (i = 0; i < len && line[i] != '='; i++) + if (i >= len && i < 1 && len - i - 1 <= 0) { + fclose(f); + return set_error(ERR_BADFMT); + } + strncpy(token, line, i); + token[i] = '\0'; + value = &line[i + 1]; + /* try to recognize the line */ + recognized = 0; + if (!strcmp(token, "version") || !strcmp(token, "build_date")) { + recognized = 1; + } + syntax = 1; + syntax = syntax && parse_token("basic_cpuid", token, value, data->basic_cpuid, MAX_CPUID_LEVEL, &recognized); + syntax = syntax && parse_token("ext_cpuid", token, value, data->ext_cpuid, MAX_EXT_CPUID_LEVEL, &recognized); + syntax = syntax && parse_token("intel_fn4", token, value, data->intel_fn4, MAX_INTELFN4_LEVEL, &recognized); + syntax = syntax && parse_token("intel_fn11", token, value, data->intel_fn11, MAX_INTELFN11_LEVEL, &recognized); + syntax = syntax && parse_token("intel_fn12h", token, value, data->intel_fn12h, MAX_INTELFN12H_LEVEL, &recognized); + syntax = syntax && parse_token("intel_fn14h", token, value, data->intel_fn14h, MAX_INTELFN14H_LEVEL, &recognized); + if (!syntax) { + warnf("Error: %s:%d: Syntax error\n", filename, cur_line); + fclose(f); + return set_error(ERR_BADFMT); + } + if (!recognized) { + warnf("Warning: %s:%d not understood!\n", filename, cur_line); + } + } + + if (strcmp(filename, "")) + fclose(f); + return set_error(ERR_OK); +} + int cpu_ident_internal(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal) { int r; @@ -432,7 +533,239 @@ int cpu_identify(struct cpu_raw_data_t* raw, struct cpu_id_t* data) return cpu_ident_internal(raw, data, &throwaway); } +const char* cpu_feature_str(cpu_feature_t feature) +{ + const struct { cpu_feature_t feature; const char* name; } + matchtable[] = { + { CPU_FEATURE_FPU, "fpu" }, + { CPU_FEATURE_VME, "vme" }, + { CPU_FEATURE_DE, "de" }, + { CPU_FEATURE_PSE, "pse" }, + { CPU_FEATURE_TSC, "tsc" }, + { CPU_FEATURE_MSR, "msr" }, + { CPU_FEATURE_PAE, "pae" }, + { CPU_FEATURE_MCE, "mce" }, + { CPU_FEATURE_CX8, "cx8" }, + { CPU_FEATURE_APIC, "apic" }, + { CPU_FEATURE_MTRR, "mtrr" }, + { CPU_FEATURE_SEP, "sep" }, + { CPU_FEATURE_PGE, "pge" }, + { CPU_FEATURE_MCA, "mca" }, + { CPU_FEATURE_CMOV, "cmov" }, + { CPU_FEATURE_PAT, "pat" }, + { CPU_FEATURE_PSE36, "pse36" }, + { CPU_FEATURE_PN, "pn" }, + { CPU_FEATURE_CLFLUSH, "clflush" }, + { CPU_FEATURE_DTS, "dts" }, + { CPU_FEATURE_ACPI, "acpi" }, + { CPU_FEATURE_MMX, "mmx" }, + { CPU_FEATURE_FXSR, "fxsr" }, + { CPU_FEATURE_SSE, "sse" }, + { CPU_FEATURE_SSE2, "sse2" }, + { CPU_FEATURE_SS, "ss" }, + { CPU_FEATURE_HT, "ht" }, + { CPU_FEATURE_TM, "tm" }, + { CPU_FEATURE_IA64, "ia64" }, + { CPU_FEATURE_PBE, "pbe" }, + { CPU_FEATURE_PNI, "pni" }, + { CPU_FEATURE_PCLMUL, "pclmul" }, + { CPU_FEATURE_DTS64, "dts64" }, + { CPU_FEATURE_MONITOR, "monitor" }, + { CPU_FEATURE_DS_CPL, "ds_cpl" }, + { CPU_FEATURE_VMX, "vmx" }, + { CPU_FEATURE_SMX, "smx" }, + { CPU_FEATURE_EST, "est" }, + { CPU_FEATURE_TM2, "tm2" }, + { CPU_FEATURE_SSSE3, "ssse3" }, + { CPU_FEATURE_CID, "cid" }, + { CPU_FEATURE_CX16, "cx16" }, + { CPU_FEATURE_XTPR, "xtpr" }, + { CPU_FEATURE_PDCM, "pdcm" }, + { CPU_FEATURE_DCA, "dca" }, + { CPU_FEATURE_SSE4_1, "sse4_1" }, + { CPU_FEATURE_SSE4_2, "sse4_2" }, + { CPU_FEATURE_SYSCALL, "syscall" }, + { CPU_FEATURE_XD, "xd" }, + { CPU_FEATURE_X2APIC, "x2apic"}, + { CPU_FEATURE_MOVBE, "movbe" }, + { CPU_FEATURE_POPCNT, "popcnt" }, + { CPU_FEATURE_AES, "aes" }, + { CPU_FEATURE_XSAVE, "xsave" }, + { CPU_FEATURE_OSXSAVE, "osxsave" }, + { CPU_FEATURE_AVX, "avx" }, + { CPU_FEATURE_MMXEXT, "mmxext" }, + { CPU_FEATURE_3DNOW, "3dnow" }, + { CPU_FEATURE_3DNOWEXT, "3dnowext" }, + { CPU_FEATURE_NX, "nx" }, + { CPU_FEATURE_FXSR_OPT, "fxsr_opt" }, + { CPU_FEATURE_RDTSCP, "rdtscp" }, + { CPU_FEATURE_LM, "lm" }, + { CPU_FEATURE_LAHF_LM, "lahf_lm" }, + { CPU_FEATURE_CMP_LEGACY, "cmp_legacy" }, + { CPU_FEATURE_SVM, "svm" }, + { CPU_FEATURE_SSE4A, "sse4a" }, + { CPU_FEATURE_MISALIGNSSE, "misalignsse" }, + { CPU_FEATURE_ABM, "abm" }, + { CPU_FEATURE_3DNOWPREFETCH, "3dnowprefetch" }, + { CPU_FEATURE_OSVW, "osvw" }, + { CPU_FEATURE_IBS, "ibs" }, + { CPU_FEATURE_SSE5, "sse5" }, + { CPU_FEATURE_SKINIT, "skinit" }, + { CPU_FEATURE_WDT, "wdt" }, + { CPU_FEATURE_TS, "ts" }, + { CPU_FEATURE_FID, "fid" }, + { CPU_FEATURE_VID, "vid" }, + { CPU_FEATURE_TTP, "ttp" }, + { CPU_FEATURE_TM_AMD, "tm_amd" }, + { CPU_FEATURE_STC, "stc" }, + { CPU_FEATURE_100MHZSTEPS, "100mhzsteps" }, + { CPU_FEATURE_HWPSTATE, "hwpstate" }, + { CPU_FEATURE_CONSTANT_TSC, "constant_tsc" }, + { CPU_FEATURE_XOP, "xop" }, + { CPU_FEATURE_FMA3, "fma3" }, + { CPU_FEATURE_FMA4, "fma4" }, + { CPU_FEATURE_TBM, "tbm" }, + { CPU_FEATURE_F16C, "f16c" }, + { CPU_FEATURE_RDRAND, "rdrand" }, + { CPU_FEATURE_CPB, "cpb" }, + { CPU_FEATURE_APERFMPERF, "aperfmperf" }, + { CPU_FEATURE_PFI, "pfi" }, + { CPU_FEATURE_PA, "pa" }, + { CPU_FEATURE_AVX2, "avx2" }, + { CPU_FEATURE_BMI1, "bmi1" }, + { CPU_FEATURE_BMI2, "bmi2" }, + { CPU_FEATURE_HLE, "hle" }, + { CPU_FEATURE_RTM, "rtm" }, + { CPU_FEATURE_AVX512F, "avx512f" }, + { CPU_FEATURE_AVX512DQ, "avx512dq" }, + { CPU_FEATURE_AVX512PF, "avx512pf" }, + { CPU_FEATURE_AVX512ER, "avx512er" }, + { CPU_FEATURE_AVX512CD, "avx512cd" }, + { CPU_FEATURE_SHA_NI, "sha_ni" }, + { CPU_FEATURE_AVX512BW, "avx512bw" }, + { CPU_FEATURE_AVX512VL, "avx512vl" }, + { CPU_FEATURE_SGX, "sgx" }, + { CPU_FEATURE_RDSEED, "rdseed" }, + { CPU_FEATURE_ADX, "adx" }, + }; + unsigned i, n = COUNT_OF(matchtable); + if (n != NUM_CPU_FEATURES) { + warnf("Warning: incomplete library, feature matchtable size differs from the actual number of features.\n"); + } + for (i = 0; i < n; i++) + if (matchtable[i].feature == feature) + return matchtable[i].name; + return ""; +} + +const char* cpuid_error(void) +{ + const struct { cpu_error_t error; const char *description; } + matchtable[] = { + { ERR_OK , "No error"}, + { ERR_NO_CPUID , "CPUID instruction is not supported"}, + { ERR_NO_RDTSC , "RDTSC instruction is not supported"}, + { ERR_NO_MEM , "Memory allocation failed"}, + { ERR_OPEN , "File open operation failed"}, + { ERR_BADFMT , "Bad file format"}, + { ERR_NOT_IMP , "Not implemented"}, + { ERR_CPU_UNKN , "Unsupported processor"}, + { ERR_NO_RDMSR , "RDMSR instruction is not supported"}, + { ERR_NO_DRIVER, "RDMSR driver error (generic)"}, + { ERR_NO_PERMS , "No permissions to install RDMSR driver"}, + { ERR_EXTRACT , "Cannot extract RDMSR driver (read only media?)"}, + { ERR_HANDLE , "Bad handle"}, + { ERR_INVMSR , "Invalid MSR"}, + { ERR_INVCNB , "Invalid core number"}, + { ERR_HANDLE_R , "Error on handle read"}, + { ERR_INVRANGE , "Invalid given range"}, + }; + unsigned i; + for (i = 0; i < COUNT_OF(matchtable); i++) + if (_libcpiud_errno == matchtable[i].error) + return matchtable[i].description; + return "Unknown error"; +} + + const char* cpuid_lib_version(void) { return VERSION; } + +libcpuid_warn_fn_t cpuid_set_warn_function(libcpuid_warn_fn_t new_fn) +{ + libcpuid_warn_fn_t ret = _warn_fun; + _warn_fun = new_fn; + return ret; +} + +void cpuid_set_verbosiness_level(int level) +{ + _current_verboselevel = level; +} + +cpu_vendor_t cpuid_get_vendor(void) +{ + static cpu_vendor_t vendor = VENDOR_UNKNOWN; + uint32_t raw_vendor[4]; + char vendor_str[VENDOR_STR_MAX]; + + if(vendor == VENDOR_UNKNOWN) { + if (!cpuid_present()) + set_error(ERR_NO_CPUID); + else { + cpu_exec_cpuid(0, raw_vendor); + vendor = cpuid_vendor_identify(raw_vendor, vendor_str); + } + } + return vendor; +} + +void cpuid_get_cpu_list(cpu_vendor_t vendor, struct cpu_list_t* list) +{ + switch (vendor) { + case VENDOR_INTEL: + cpuid_get_list_intel(list); + break; + case VENDOR_AMD: + cpuid_get_list_amd(list); + break; + case VENDOR_CYRIX: + make_list_from_string("Cx486,Cx5x86,6x86,6x86MX,M II,MediaGX,MediaGXi,MediaGXm", list); + break; + case VENDOR_NEXGEN: + make_list_from_string("Nx586", list); + break; + case VENDOR_TRANSMETA: + make_list_from_string("Crusoe,Efficeon", list); + break; + case VENDOR_UMC: + make_list_from_string("UMC x86 CPU", list); + break; + case VENDOR_CENTAUR: + make_list_from_string("VIA C3,VIA C7,VIA Nano", list); + break; + case VENDOR_RISE: + make_list_from_string("Rise mP6", list); + break; + case VENDOR_SIS: + make_list_from_string("SiS mP6", list); + break; + case VENDOR_NSC: + make_list_from_string("Geode GXm,Geode GXLV,Geode GX1,Geode GX2", list); + break; + default: + warnf("Unknown vendor passed to cpuid_get_cpu_list()\n"); + break; + } +} + +void cpuid_free_cpu_list(struct cpu_list_t* list) +{ + int i; + if (list->num_entries <= 0) return; + for (i = 0; i < list->num_entries; i++) + free(list->names[i]); + free(list->names); +} diff --git a/compat/libcpuid/intel_code_t.h b/src/3rdparty/libcpuid/intel_code_t.h similarity index 100% rename from compat/libcpuid/intel_code_t.h rename to src/3rdparty/libcpuid/intel_code_t.h diff --git a/compat/libcpuid/libcpuid.h b/src/3rdparty/libcpuid/libcpuid.h similarity index 100% rename from compat/libcpuid/libcpuid.h rename to src/3rdparty/libcpuid/libcpuid.h diff --git a/compat/libcpuid/libcpuid_constants.h b/src/3rdparty/libcpuid/libcpuid_constants.h similarity index 100% rename from compat/libcpuid/libcpuid_constants.h rename to src/3rdparty/libcpuid/libcpuid_constants.h diff --git a/compat/libcpuid/libcpuid_internal.h b/src/3rdparty/libcpuid/libcpuid_internal.h similarity index 66% rename from compat/libcpuid/libcpuid_internal.h rename to src/3rdparty/libcpuid/libcpuid_internal.h index 7f3671da..038aa209 100644 --- a/compat/libcpuid/libcpuid_internal.h +++ b/src/3rdparty/libcpuid/libcpuid_internal.h @@ -58,6 +58,48 @@ struct internal_id_info_t { int score; // detection (matchtable) score }; +#define LBIT(x) (((long long) 1) << x) + +enum _common_bits_t { + _M_ = LBIT( 0 ), + MOBILE_ = LBIT( 1 ), + _MP_ = LBIT( 2 ), +}; + +// additional detection bits for Intel CPUs: +enum _intel_bits_t { + PENTIUM_ = LBIT( 10 ), + CELERON_ = LBIT( 11 ), + CORE_ = LBIT( 12 ), + _I_ = LBIT( 13 ), + _3 = LBIT( 14 ), + _5 = LBIT( 15 ), + _7 = LBIT( 16 ), + XEON_ = LBIT( 17 ), + ATOM_ = LBIT( 18 ), +}; +typedef enum _intel_bits_t intel_bits_t; + +enum _amd_bits_t { + ATHLON_ = LBIT( 10 ), + _XP_ = LBIT( 11 ), + DURON_ = LBIT( 12 ), + SEMPRON_ = LBIT( 13 ), + OPTERON_ = LBIT( 14 ), + TURION_ = LBIT( 15 ), + _LV_ = LBIT( 16 ), + _64_ = LBIT( 17 ), + _X2 = LBIT( 18 ), + _X3 = LBIT( 19 ), + _X4 = LBIT( 20 ), + _X6 = LBIT( 21 ), + _FX = LBIT( 22 ), + _APU_ = LBIT( 23 ), +}; +typedef enum _amd_bits_t amd_bits_t; + + + int cpu_ident_internal(struct cpu_raw_data_t* raw, struct cpu_id_t* data, struct internal_id_info_t* internal); diff --git a/compat/libcpuid/libcpuid_types.h b/src/3rdparty/libcpuid/libcpuid_types.h similarity index 100% rename from compat/libcpuid/libcpuid_types.h rename to src/3rdparty/libcpuid/libcpuid_types.h diff --git a/compat/libcpuid/libcpuid_util.c b/src/3rdparty/libcpuid/libcpuid_util.c similarity index 100% rename from compat/libcpuid/libcpuid_util.c rename to src/3rdparty/libcpuid/libcpuid_util.c diff --git a/compat/libcpuid/libcpuid_util.h b/src/3rdparty/libcpuid/libcpuid_util.h similarity index 98% rename from compat/libcpuid/libcpuid_util.h rename to src/3rdparty/libcpuid/libcpuid_util.h index aba63f1a..c3b53933 100644 --- a/compat/libcpuid/libcpuid_util.h +++ b/src/3rdparty/libcpuid/libcpuid_util.h @@ -28,8 +28,6 @@ #define COUNT_OF(array) (sizeof(array) / sizeof(array[0])) -#define LBIT(x) (((long long) 1) << x) - struct feature_map_t { unsigned bit; cpu_feature_t feature; diff --git a/compat/libcpuid/recog_amd.c b/src/3rdparty/libcpuid/recog_amd.c similarity index 98% rename from compat/libcpuid/recog_amd.c rename to src/3rdparty/libcpuid/recog_amd.c index b735c400..3867aa8c 100644 --- a/compat/libcpuid/recog_amd.c +++ b/src/3rdparty/libcpuid/recog_amd.c @@ -44,26 +44,6 @@ struct amd_code_and_bits_t { uint64_t bits; }; -enum _amd_bits_t { - ATHLON_ = LBIT( 0 ), - _XP_ = LBIT( 1 ), - _M_ = LBIT( 2 ), - _MP_ = LBIT( 3 ), - MOBILE_ = LBIT( 4 ), - DURON_ = LBIT( 5 ), - SEMPRON_ = LBIT( 6 ), - OPTERON_ = LBIT( 7 ), - TURION_ = LBIT( 8 ), - _LV_ = LBIT( 9 ), - _64_ = LBIT( 10 ), - _X2 = LBIT( 11 ), - _X3 = LBIT( 12 ), - _X4 = LBIT( 13 ), - _X6 = LBIT( 14 ), - _FX = LBIT( 15 ), -}; -typedef enum _amd_bits_t amd_bits_t; - enum _amd_model_codes_t { // Only for Ryzen CPUs: _1400, @@ -469,11 +449,12 @@ static struct amd_code_and_bits_t decode_amd_codename_part1(const char *bs) if (strstr(bs, "XP")) bits |= _XP_; if (strstr(bs, "XP-M")) bits |= _M_; if (strstr(bs, "(LV)")) bits |= _LV_; + if (strstr(bs, " APU ")) bits |= _APU_; if (match_pattern(bs, "C-##")) code = FUSION_C; if (match_pattern(bs, "E-###")) code = FUSION_E; if (match_pattern(bs, "Z-##")) code = FUSION_Z; - if (match_pattern(bs, "E#-####") || match_pattern(bs, "A#-####")) code = FUSION_EA; + if (match_pattern(bs, "[EA]#-####")) code = FUSION_EA; result.code = code; result.bits = bits; diff --git a/compat/libcpuid/recog_amd.h b/src/3rdparty/libcpuid/recog_amd.h similarity index 100% rename from compat/libcpuid/recog_amd.h rename to src/3rdparty/libcpuid/recog_amd.h diff --git a/compat/libcpuid/recog_intel.c b/src/3rdparty/libcpuid/recog_intel.c similarity index 98% rename from compat/libcpuid/recog_intel.c rename to src/3rdparty/libcpuid/recog_intel.c index 1d6c6a84..5e6c03b0 100644 --- a/compat/libcpuid/recog_intel.c +++ b/src/3rdparty/libcpuid/recog_intel.c @@ -59,23 +59,6 @@ enum _intel_model_t { }; typedef enum _intel_model_t intel_model_t; -enum _intel_bits_t { - PENTIUM_ = LBIT( 0 ), - CELERON_ = LBIT( 1 ), - MOBILE_ = LBIT( 2 ), - CORE_ = LBIT( 3 ), - _I_ = LBIT( 4 ), - _M_ = LBIT( 5 ), - _3 = LBIT( 6 ), - _5 = LBIT( 7 ), - _7 = LBIT( 8 ), - XEON_ = LBIT( 9 ), - _MP = LBIT( 10 ), - ATOM_ = LBIT( 11 ), - -}; -typedef enum _intel_bits_t intel_bits_t; - const struct match_entry_t cpudb_intel[] = { { -1, -1, -1, -1, -1, 1, -1, -1, NC, 0 , 0, "Unknown Intel CPU" }, @@ -158,11 +141,11 @@ const struct match_entry_t cpudb_intel[] = { { 15, 0, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Foster)" }, { 15, 1, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Foster)" }, { 15, 2, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Prestonia)" }, - { 15, 2, -1, 15, -1, 1, -1, -1, NC, XEON_|_MP , 0, "Xeon (Gallatin)" }, + { 15, 2, -1, 15, -1, 1, -1, -1, NC, XEON_|_MP_ , 0, "Xeon (Gallatin)" }, { 15, 3, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Nocona)" }, { 15, 4, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Nocona)" }, { 15, 4, -1, 15, -1, 1, -1, -1, IRWIN, XEON_ , 0, "Xeon (Irwindale)" }, - { 15, 4, -1, 15, -1, 1, -1, -1, NC, XEON_|_MP , 0, "Xeon (Cranford)" }, + { 15, 4, -1, 15, -1, 1, -1, -1, NC, XEON_|_MP_ , 0, "Xeon (Cranford)" }, { 15, 4, -1, 15, -1, 1, -1, -1, POTOMAC, XEON_ , 0, "Xeon (Potomac)" }, { 15, 6, -1, 15, -1, 1, -1, -1, NC, XEON_ , 0, "Xeon (Dempsey)" }, @@ -668,7 +651,7 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data) const struct { uint64_t bit; const char* search; } bit_matchtable[] = { { XEON_, "Xeon" }, - { _MP, " MP" }, + { _MP_, " MP" }, { ATOM_, "Atom(TM) CPU" }, { MOBILE_, "Mobile" }, { CELERON_, "Celeron" }, @@ -710,7 +693,7 @@ static intel_code_and_bits_t get_brand_code_and_bits(struct cpu_id_t* data) /* restrict by family, since later Xeons also have L3 ... */ code = IRWIN; } - if (match_all(bits, XEON_ + _MP) && data->l3_cache > 0) + if (match_all(bits, XEON_ + _MP_) && data->l3_cache > 0) code = POTOMAC; if (code == CORE_SOLO) { s = strstr(bs, "CPU"); diff --git a/compat/libcpuid/recog_intel.h b/src/3rdparty/libcpuid/recog_intel.h similarity index 100% rename from compat/libcpuid/recog_intel.h rename to src/3rdparty/libcpuid/recog_intel.h diff --git a/src/Cpu.cpp b/src/Cpu.cpp index 8140cd5f..53d81e58 100644 --- a/src/Cpu.cpp +++ b/src/Cpu.cpp @@ -22,3 +22,84 @@ */ +#include +#include +#include + +#include "Cpu.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; +int Cpu::m_totalThreads = 0; + + +int Cpu::optimalThreadsCount(int algo, bool doubleHash, int maxCpuUsage) +{ + if (m_totalThreads == 1) { + return 1; + } + + int cache = m_l3_cache ? m_l3_cache : m_l2_cache; + int count = 0; + const int size = (algo ? 1024 : 2048) * (doubleHash ? 2 : 1); + + if (cache) { + count = cache / size; + } + else { + count = m_totalThreads / 2; + } + + if (count > m_totalThreads) { + count = m_totalThreads; + } + + if (((float) count / m_totalThreads * 100) > maxCpuUsage) { + count = ceil((float) m_totalThreads * (maxCpuUsage / 100.0)); + } + + return count < 1 ? 1 : count; +} + + +void Cpu::initCommon() +{ + struct cpu_raw_data_t raw = { 0 }; + struct cpu_id_t data = { 0 }; + + cpuid_get_raw_data(&raw); + cpu_identify(&raw, &data); + + 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_totalCores = data.num_cores *m_sockets; + + m_l3_cache = 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.l3_cache <= 0 && data.l2_assoc == 16 && data.ext_family >= 21) { + m_l2_cache = data.l2_cache * (m_totalCores / 2) * m_sockets; + } + else { + m_l2_cache = data.l2_cache > 0 ? data.l2_cache * m_totalCores * m_sockets : 0; + } + +# ifdef __x86_64__ + m_flags |= X86_64; +# endif + + if (data.flags[CPU_FEATURE_AES]) { + m_flags |= AES; + } + + if (data.flags[CPU_FEATURE_BMI2]) { + m_flags |= BMI2; + } +} diff --git a/src/Summary.cpp b/src/Summary.cpp index 4e047360..38f1b1c5 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -25,14 +25,13 @@ #include -#include "Summary.h" #include "Console.h" #include "Cpu.h" #include "Options.h" +#include "Summary.h" #include "version.h" - static void print_versions() { char *buf = static_cast(malloc(16));