From e6d4921e2169dea12cdab9f0a4a23b5a384306cf Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 26 Jan 2021 16:40:10 +0700 Subject: [PATCH 01/18] v6.8.1-dev --- src/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/version.h b/src/version.h index fb458fa3..98b9fa9f 100644 --- a/src/version.h +++ b/src/version.h @@ -28,7 +28,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.8.0" +#define APP_VERSION "6.8.1-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2021 xmrig.com" @@ -36,7 +36,7 @@ #define APP_VER_MAJOR 6 #define APP_VER_MINOR 8 -#define APP_VER_PATCH 0 +#define APP_VER_PATCH 1 #ifdef _MSC_VER # if (_MSC_VER >= 1920) From 65fe26dc6c6545aeb48fdf9531d51969899af6b0 Mon Sep 17 00:00:00 2001 From: XMRig Date: Thu, 28 Jan 2021 00:00:00 +0700 Subject: [PATCH 02/18] Don't print empty memory slots if the total count above 8. --- src/Summary.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Summary.cpp b/src/Summary.cpp index eaee89bf..39b37ac0 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -146,7 +146,7 @@ static void print_memory(const Config *config) return; } - const bool vm = Cpu::info()->isVM(); + const bool printEmpty = reader.memory().size() <= 8; for (const auto &memory : reader.memory()) { if (!memory.isValid()) { @@ -157,12 +157,12 @@ static void print_memory(const Config *config) Log::print(WHITE_BOLD(" %-13s") "%s: " CYAN_BOLD("%" PRIu64) CYAN(" GB ") WHITE_BOLD("%s @ %" PRIu64 " MHz ") BLACK_BOLD("%s"), "", memory.slot().data(), memory.size() / oneGiB, memory.type(), memory.speed() / 1000000ULL, memory.product().data()); } - else if (!vm) { + else if (printEmpty) { Log::print(WHITE_BOLD(" %-13s") "%s: " BLACK_BOLD(""), "", memory.slot().data()); } } - const auto &board = vm ? reader.system() : reader.board(); + const auto &board = Cpu::info()->isVM() ? reader.system() : reader.board(); if (board.isValid()) { Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s") " - " WHITE_BOLD("%s"), "MOTHERBOARD", board.vendor().data(), board.product().data()); From f302b4b0ef2ba9d6052bab50fe238210eeb204b6 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Thu, 28 Jan 2021 13:37:27 +0100 Subject: [PATCH 03/18] Added documentation for config.json CPU options --- doc/CPU.md | 54 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/doc/CPU.md b/doc/CPU.md index 385af6ad..508f1e2c 100644 --- a/doc/CPU.md +++ b/doc/CPU.md @@ -75,6 +75,35 @@ Each number represent one thread and means CPU affinity, this is default format ``` Internal format, but can be user defined. +## RandomX options + +#### `init` +Thread count to initialize RandomX dataset. Auto-detect (`-1`) or any number greater than 0 to use that many threads. + +#### `init-avx2` +Use AVX2 for dataset initialization. Faster on some CPUs. Auto-detect (`-1`), disabled (`0`), always enabled on CPUs that support AVX2 (`1`). + +#### `mode` +RandomX mining mode: `auto`, `fast` (2 GB memory), `light` (256 MB memory). + +#### `1gb-pages` +Use 1GB hugepages for RandomX dataset (Linux only). Enabled (`true`) or disabled (`false`). It gives 1-3% speedup. + +#### `rdmsr` +Restore MSR register values to their original values on exit. Used together with `wrmsr`. Enabled (`true`) or disabled (`false`). + +#### `wrmsr` +[MSR mod](https://xmrig.com/docs/miner/randomx-optimization-guide/msr). Enabled (`true`) or disabled (`false`). It gives up to 15% speedup depending on your system. + +#### `cache_qos` +[Cache QoS](https://xmrig.com/docs/miner/randomx-optimization-guide/qos). Enabled (`true`) or disabled (`false`). It's useful when you can't or don't want to mine on all CPU cores to make mining hashrate more stable. + +#### `numa` +NUMA support (better hashrate on multi-CPU servers and Ryzen Threadripper 1xxx/2xxx). Enabled (`true`) or disabled (`false`). + +#### `scratchpad_prefetch_mode` +Which instruction to use in RandomX loop to prefetch data from scratchpad. `1` is default and fastest in most cases. Can be off (`0`), `prefetcht0` instruction (`1`), `prefetchnta` instruction (`2`, a bit faster on Coffee Lake and a few other CPUs), `mov` instruction (`3`). + ## Shared options #### `enabled` @@ -83,23 +112,32 @@ Enable (`true`) or disable (`false`) CPU backend, by default `true`. #### `huge-pages` Enable (`true`) or disable (`false`) huge pages support, by default `true`. +#### `huge-pages-jit` +Enable (`true`) or disable (`false`) huge pages support for RandomX JIT code, by default `false`. It gives a very small boost on Ryzen CPUs, but hashrate is unstable between launches. Use with caution. + #### `hw-aes` Force enable (`true`) or disable (`false`) hardware AES support. Default value `null` means miner autodetect this feature. Usually don't need change this option, this option useful for some rare cases when miner can't detect hardware AES, but it available. If you force enable this option, but your hardware not support it, miner will crash. #### `priority` -Mining threads priority, value from `1` (lowest priority) to `5` (highest possible priority). Default value `null` means miner don't change threads priority at all. +Mining threads priority, value from `1` (lowest priority) to `5` (highest possible priority). Default value `null` means miner don't change threads priority at all. Setting priority higher than 2 can make your PC unresponsive. + +#### `memory-pool` (since v4.3.0) +Use continuous, persistent memory block for mining threads, useful for preserve huge pages allocation while algorithm swithing. Possible values `false` (feature disabled, by default) or `true` or specific count of 2 MB huge pages. It helps to avoid loosing huge pages for scratchpads when RandomX dataset is updated and mining threads restart after a 2-3 days of mining. + +#### `yield` (since v5.1.1) +Prefer system better system response/stability `true` (default value) or maximum hashrate `false`. #### `asm` Enable/configure or disable ASM optimizations. Possible values: `true`, `false`, `"intel"`, `"ryzen"`, `"bulldozer"`. #### `argon2-impl` (since v3.1.0) -Allow override automatically detected Argon2 implementation, this option added mostly for debug purposes, default value `null` means autodetect. Other possible values: `"x86_64"`, `"SSE2"`, `"SSSE3"`, `"XOP"`, `"AVX2"`, `"AVX-512F"`. Manual selection has no safe guards, if you CPU not support required instuctions, miner will crash. +Allow override automatically detected Argon2 implementation, this option added mostly for debug purposes, default value `null` means autodetect. This is used in RandomX dataset initialization and also in some other mining algorithms. Other possible values: `"x86_64"`, `"SSE2"`, `"SSSE3"`, `"XOP"`, `"AVX2"`, `"AVX-512F"`. Manual selection has no safe guards - if your CPU doesn't support required instuctions, miner will crash. + +#### `astrobwt-max-size` +AstroBWT algorithm: skip hashes with large stage 2 size, default: `550`, min: `400`, max: `1200`. Optimal value depends on your CPU/GPU + +#### `astrobwt-avx2` +AstroBWT algorithm: use AVX2 code. It's faster on some CPUs and slower on other #### `max-threads-hint` (since v4.2.0) Maximum CPU threads count (in percentage) hint for autoconfig. [CPU_MAX_USAGE.md](CPU_MAX_USAGE.md) - -#### `memory-pool` (since v4.3.0) -Use continuous, persistent memory block for mining threads, useful for preserve huge pages allocation while algorithm swithing. Possible values `false` (feature disabled, by default) or `true` or specific count of 2 MB huge pages. - -#### `yield` (since v5.1.1) -Prefer system better system response/stability `true` (default value) or maximum hashrate `false`. From 22a1b8d82d524d8f19492617f97017f34468253e Mon Sep 17 00:00:00 2001 From: SChernykh Date: Thu, 28 Jan 2021 14:38:28 +0100 Subject: [PATCH 04/18] Fix compilation error when RandomX and Argon2 are disabled --- src/core/config/ConfigTransform.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/config/ConfigTransform.cpp b/src/core/config/ConfigTransform.cpp index b32aede3..10f819e4 100644 --- a/src/core/config/ConfigTransform.cpp +++ b/src/core/config/ConfigTransform.cpp @@ -149,8 +149,10 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const case IConfig::YieldKey: /* --cpu-no-yield */ return set(doc, CpuConfig::kField, CpuConfig::kYield, false); +# ifdef XMRIG_ALGO_ARGON2 case IConfig::Argon2ImplKey: /* --argon2-impl */ return set(doc, CpuConfig::kField, CpuConfig::kArgon2Impl, arg); +# endif # ifdef XMRIG_FEATURE_ASM case IConfig::AssemblyKey: /* --asm */ From 9ca1a6129b98d5d003c03db49b170dce4fcefb98 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 29 Jan 2021 01:23:35 +0700 Subject: [PATCH 05/18] #2066 Quick fix for AMD GPUs health data. --- src/backend/opencl/wrappers/AdlLib_linux.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/backend/opencl/wrappers/AdlLib_linux.cpp b/src/backend/opencl/wrappers/AdlLib_linux.cpp index b297ec71..3a0738ee 100644 --- a/src/backend/opencl/wrappers/AdlLib_linux.cpp +++ b/src/backend/opencl/wrappers/AdlLib_linux.cpp @@ -1,8 +1,8 @@ /* XMRig - * Copyright 2008-2018 Advanced Micro Devices, Inc. - * Copyright 2018-2020 SChernykh - * Copyright 2020 Patrick Bollinger - * Copyright 2016-2020 XMRig , + * Copyright (c) 2008-2018 Advanced Micro Devices, Inc. + * Copyright (c) 2020 Patrick Bollinger + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 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 @@ -81,7 +81,7 @@ static inline std::string sysfs_prefix(const PciTopology &topology) { const std::string path = kPrefix + "0000:" + topology.toString().data() + "/hwmon/hwmon"; - for (uint32_t i = 1; i < 10; ++i) { + for (uint32_t i = 1; i < 100; ++i) { const std::string prefix = path + std::to_string(i) + "/"; if (sysfs_is_amdgpu(prefix + "name") && (sysfs_read(prefix + "temp1_input") || sysfs_read(prefix + "power1_average"))) { return prefix; From f68b105bd9d2fb2d8e963637770a813dbde7c701 Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 29 Jan 2021 04:23:50 +0700 Subject: [PATCH 06/18] Normalize DMI memory slot name. --- src/Summary.cpp | 2 +- src/hw/dmi/DmiMemory.cpp | 28 ++++++++++++++++++++++++++-- src/hw/dmi/DmiMemory.h | 4 ++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/Summary.cpp b/src/Summary.cpp index 39b37ac0..6b12e62f 100644 --- a/src/Summary.cpp +++ b/src/Summary.cpp @@ -155,7 +155,7 @@ static void print_memory(const Config *config) if (memory.size()) { Log::print(WHITE_BOLD(" %-13s") "%s: " CYAN_BOLD("%" PRIu64) CYAN(" GB ") WHITE_BOLD("%s @ %" PRIu64 " MHz ") BLACK_BOLD("%s"), - "", memory.slot().data(), memory.size() / oneGiB, memory.type(), memory.speed() / 1000000ULL, memory.product().data()); + "", memory.id().data(), memory.size() / oneGiB, memory.type(), memory.speed() / 1000000ULL, memory.product().data()); } else if (printEmpty) { Log::print(WHITE_BOLD(" %-13s") "%s: " BLACK_BOLD(""), "", memory.slot().data()); diff --git a/src/hw/dmi/DmiMemory.cpp b/src/hw/dmi/DmiMemory.cpp index 05af0962..480ad4b3 100644 --- a/src/hw/dmi/DmiMemory.cpp +++ b/src/hw/dmi/DmiMemory.cpp @@ -20,17 +20,22 @@ #include "hw/dmi/DmiMemory.h" +#include "3rdparty/fmt/format.h" #include "3rdparty/rapidjson/document.h" #include "hw/dmi/DmiTools.h" #include #include +#include namespace xmrig { +static const char *kIdFormat = "DIMM_{}{}"; + + static inline uint16_t dmi_memory_device_width(uint16_t code) { return (code == 0xFFFF || code == 0) ? 0 : code; @@ -143,9 +148,9 @@ xmrig::DmiMemory::DmiMemory(dmi_header *h) m_size = (1024ULL * (size & 0x7FFF) * ((size & 0x8000) ? 1 : 1024ULL)); } + setId(dmi_string(h, 0x10), dmi_string(h, 0x11)); + m_formFactor = h->data[0x0E]; - m_slot = dmi_string(h, 0x10); - m_bank = dmi_string(h, 0x11); m_type = h->data[0x12]; if (!m_size || h->length < 0x17) { @@ -201,6 +206,7 @@ rapidjson::Value xmrig::DmiMemory::toJSON(rapidjson::Document &doc) const auto &allocator = doc.GetAllocator(); Value out(kObjectType); + out.AddMember("id", id().toJSON(doc), allocator); out.AddMember("slot", m_slot.toJSON(doc), allocator); out.AddMember("type", StringRef(type()), allocator); out.AddMember("form_factor", StringRef(formFactor()), allocator); @@ -217,3 +223,21 @@ rapidjson::Value xmrig::DmiMemory::toJSON(rapidjson::Document &doc) const return out; } #endif + + +void xmrig::DmiMemory::setId(const char *slot, const char *bank) +{ + m_slot = slot; + m_bank = bank; + + std::cmatch cm; + if (std::regex_match(slot, cm, std::regex("^Channel([A-Z])-DIMM(\\d+)$"))) { + m_id = fmt::format(kIdFormat, cm.str(1), cm.str(2)).c_str(); + } + else if (std::regex_search(bank, cm, std::regex("CHANNEL ([A-Z])$"))) { + std::cmatch cm2; + if (std::regex_match(slot, cm2, std::regex("^DIMM (\\d+)$"))) { + m_id = fmt::format(kIdFormat, cm.str(1), cm2.str(1)).c_str(); + } + } +} diff --git a/src/hw/dmi/DmiMemory.h b/src/hw/dmi/DmiMemory.h index badee2cf..589b3b90 100644 --- a/src/hw/dmi/DmiMemory.h +++ b/src/hw/dmi/DmiMemory.h @@ -39,6 +39,7 @@ public: inline bool isValid() const { return !m_slot.isEmpty(); } inline const String &bank() const { return m_bank; } + inline const String &id() const { return m_id.isNull() ? m_slot : m_id; } inline const String &product() const { return m_product; } inline const String &slot() const { return m_slot; } inline const String &vendor() const { return m_vendor; } @@ -57,7 +58,10 @@ public: # endif private: + void setId(const char *slot, const char *bank); + String m_bank; + String m_id; String m_product; String m_slot; String m_vendor; From 7d52bd7454404e1aec164dcb8c8067623e20922b Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 29 Jan 2021 18:22:24 +0700 Subject: [PATCH 07/18] Extend normalization rules. --- src/hw/dmi/DmiMemory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hw/dmi/DmiMemory.cpp b/src/hw/dmi/DmiMemory.cpp index 480ad4b3..735af286 100644 --- a/src/hw/dmi/DmiMemory.cpp +++ b/src/hw/dmi/DmiMemory.cpp @@ -231,7 +231,7 @@ void xmrig::DmiMemory::setId(const char *slot, const char *bank) m_bank = bank; std::cmatch cm; - if (std::regex_match(slot, cm, std::regex("^Channel([A-Z])-DIMM(\\d+)$"))) { + if (std::regex_match(slot, cm, std::regex("^Channel([A-Z])[-_]DIMM(\\d+)$", std::regex_constants::icase))) { m_id = fmt::format(kIdFormat, cm.str(1), cm.str(2)).c_str(); } else if (std::regex_search(bank, cm, std::regex("CHANNEL ([A-Z])$"))) { From 2c52a5a352167c37cbc5f854e15ec261c67e1cb7 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sat, 30 Jan 2021 02:42:59 +0700 Subject: [PATCH 08/18] #2066 Fixed AMD GPUs health data readings. --- src/backend/common/misc/PciTopology.h | 26 +++---- src/backend/opencl/wrappers/AdlLib_linux.cpp | 82 +++++++++++++++----- 2 files changed, 75 insertions(+), 33 deletions(-) diff --git a/src/backend/common/misc/PciTopology.h b/src/backend/common/misc/PciTopology.h index ee531f50..af1844c9 100644 --- a/src/backend/common/misc/PciTopology.h +++ b/src/backend/common/misc/PciTopology.h @@ -1,13 +1,6 @@ /* 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 2018 Lee Clagett - * Copyright 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 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 @@ -42,10 +35,15 @@ public: PciTopology() = default; PciTopology(uint32_t bus, uint32_t device, uint32_t function) : m_valid(true), m_bus(bus), m_device(device), m_function(function) {} - inline bool isValid() const { return m_valid; } - inline uint8_t bus() const { return m_bus; } - inline uint8_t device() const { return m_device; } - inline uint8_t function() const { return m_function; } + inline bool isEqual(const PciTopology &other) const { return m_valid == other.m_valid && toUint32() == other.toUint32(); } + inline bool isValid() const { return m_valid; } + inline uint8_t bus() const { return m_bus; } + inline uint8_t device() const { return m_device; } + inline uint8_t function() const { return m_function; } + + inline bool operator!=(const PciTopology &other) const { return !isEqual(other); } + inline bool operator<(const PciTopology &other) const { return toUint32() < other.toUint32(); } + inline bool operator==(const PciTopology &other) const { return isEqual(other); } String toString() const { @@ -60,6 +58,8 @@ public: } private: + inline uint32_t toUint32() const { return m_bus << 16 | m_device << 8 | m_function; } + bool m_valid = false; uint8_t m_bus = 0; uint8_t m_device = 0; diff --git a/src/backend/opencl/wrappers/AdlLib_linux.cpp b/src/backend/opencl/wrappers/AdlLib_linux.cpp index 3a0738ee..7d7adb31 100644 --- a/src/backend/opencl/wrappers/AdlLib_linux.cpp +++ b/src/backend/opencl/wrappers/AdlLib_linux.cpp @@ -20,10 +20,13 @@ #include "backend/opencl/wrappers/AdlLib.h" +#include "3rdparty/fmt/core.h" #include "backend/opencl/wrappers/OclDevice.h" +#include #include +#include #include #include #include @@ -35,18 +38,27 @@ namespace xmrig { bool AdlLib::m_initialized = false; bool AdlLib::m_ready = false; static const std::string kPrefix = "/sys/bus/pci/drivers/amdgpu/"; +static std::map hwmon_cache; -static inline bool sysfs_is_file(const std::string &path) +static inline bool sysfs_is_file(const char *path) { struct stat sb; - return stat(path.c_str(), &sb) == 0 && ((sb.st_mode & S_IFMT) == S_IFREG); + return stat(path, &sb) == 0 && ((sb.st_mode & S_IFMT) == S_IFREG); } -static inline bool sysfs_is_amdgpu(const std::string &path) +static inline int dir_filter(const struct dirent *dirp) { + return strlen(dirp->d_name) > 5 ? 1 : 0; +} + + +static bool sysfs_is_amdgpu(const char *path, char *buf, const char *filename) +{ + strcpy(buf, filename); + if (!sysfs_is_file(path)) { return false; } @@ -63,8 +75,10 @@ static inline bool sysfs_is_amdgpu(const std::string &path) } -uint32_t sysfs_read(const std::string &path) +static uint32_t sysfs_read(const char *path, char *buf, const char *filename) { + strcpy(buf, filename); + std::ifstream file(path); if (!file.is_open()) { return 0; @@ -77,18 +91,44 @@ uint32_t sysfs_read(const std::string &path) } -static inline std::string sysfs_prefix(const PciTopology &topology) +static size_t sysfs_prefix(char path[PATH_MAX], const PciTopology &topology) { - const std::string path = kPrefix + "0000:" + topology.toString().data() + "/hwmon/hwmon"; + const auto it = hwmon_cache.find(topology); + if (it != hwmon_cache.end()) { + strcpy(path, it->second.data()); - for (uint32_t i = 1; i < 100; ++i) { - const std::string prefix = path + std::to_string(i) + "/"; - if (sysfs_is_amdgpu(prefix + "name") && (sysfs_read(prefix + "temp1_input") || sysfs_read(prefix + "power1_average"))) { - return prefix; - } + return it->second.size(); } - return {}; + char *base = fmt::format_to(path, "{}0000:{}/hwmon/", kPrefix, topology.toString()); + *base = '\0'; + char *end = nullptr; + + struct dirent **namelist; + int n = scandir(path, &namelist, dir_filter, nullptr); + if (n < 0) { + return {}; + } + + while (n--) { + if (!end) { + char *tmp = fmt::format_to(base, "{}/", namelist[n]->d_name); + end = (sysfs_is_amdgpu(path, tmp, "name") && (sysfs_read(path, tmp, "temp1_input") || sysfs_read(path, tmp, "power1_average"))) ? tmp : nullptr; + } + + free(namelist[n]); + } + + free(namelist); + + if (end) { + *end = '\0'; + hwmon_cache.insert({ topology, path }); + + return end - path; + } + + return 0; } @@ -124,20 +164,22 @@ AdlHealth xmrig::AdlLib::health(const OclDevice &device) return {}; } - const auto prefix = sysfs_prefix(device.topology()); - if (prefix.empty()) { + static char path[PATH_MAX]{}; + + char *buf = path + sysfs_prefix(path, device.topology()); + if (buf == path) { return {}; } AdlHealth health; - health.clock = sysfs_read(prefix + "freq1_input") / 1000000; - health.memClock = sysfs_read(prefix + "freq2_input") / 1000000; - health.power = sysfs_read(prefix + "power1_average") / 1000000; - health.rpm = sysfs_read(prefix + "fan1_input"); - health.temperature = sysfs_read(prefix + "temp2_input") / 1000; + health.clock = sysfs_read(path, buf, "freq1_input") / 1000000; + health.memClock = sysfs_read(path, buf, "freq2_input") / 1000000; + health.power = sysfs_read(path, buf, "power1_average") / 1000000; + health.rpm = sysfs_read(path, buf, "fan1_input"); + health.temperature = sysfs_read(path, buf, "temp2_input") / 1000; if (!health.temperature) { - health.temperature = sysfs_read(prefix + "temp1_input") / 1000; + health.temperature = sysfs_read(path, buf, "temp1_input") / 1000; } return health; From 62450f4ed8b3cea154fdb212c67b466df681f8eb Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 31 Jan 2021 03:53:22 +0700 Subject: [PATCH 09/18] Update ARM CPUs names. --- src/backend/cpu/platform/lscpu_arm.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/backend/cpu/platform/lscpu_arm.cpp b/src/backend/cpu/platform/lscpu_arm.cpp index 2aa4b12a..38d62109 100644 --- a/src/backend/cpu/platform/lscpu_arm.cpp +++ b/src/backend/cpu/platform/lscpu_arm.cpp @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2018 Riku Voipio - * Copyright (c) 2018-2020 SChernykh - * Copyright (c) 2016-2020 XMRig + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 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 @@ -87,16 +87,22 @@ static const id_part arm_part[] = { { 0xd03, "Cortex-A53" }, { 0xd04, "Cortex-A35" }, { 0xd05, "Cortex-A55" }, + { 0xd06, "Cortex-A65" }, { 0xd07, "Cortex-A57" }, { 0xd08, "Cortex-A72" }, { 0xd09, "Cortex-A73" }, { 0xd0a, "Cortex-A75" }, { 0xd0b, "Cortex-A76" }, { 0xd0c, "Neoverse-N1" }, + { 0xd0d, "Cortex-A77" }, + { 0xd0e, "Cortex-A76AE" }, { 0xd13, "Cortex-R52" }, { 0xd20, "Cortex-M23" }, { 0xd21, "Cortex-M33" }, + { 0xd41, "Cortex-A78" }, + { 0xd42, "Cortex-A78AE" }, { 0xd4a, "Neoverse-E1" }, + { 0xd4b, "Cortex-A78C" }, { -1, nullptr }, }; @@ -150,6 +156,7 @@ static const id_part samsung_part[] = { static const id_part nvidia_part[] = { { 0x000, "Denver" }, { 0x003, "Denver 2" }, + { 0x004, "Carmel" }, { -1, nullptr }, }; @@ -191,6 +198,11 @@ static const id_part intel_part[] = { { -1, nullptr }, }; +static const struct id_part fujitsu_part[] = { + { 0x001, "A64FX" }, + { -1, "unknown" }, +}; + static const id_part hisi_part[] = { { 0xd01, "Kunpeng-920" }, /* aka tsv110 */ { -1, nullptr }, @@ -202,6 +214,7 @@ static const hw_impl hw_implementer[] = { { 0x42, brcm_part, "Broadcom" }, { 0x43, cavium_part, "Cavium" }, { 0x44, dec_part, "DEC" }, + { 0x46, fujitsu_part, "FUJITSU" }, { 0x48, hisi_part, "HiSilicon" }, { 0x4e, nvidia_part, "Nvidia" }, { 0x50, apm_part, "APM" }, From 8faef28e7da5cff809778269ca62a328aa05fed0 Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 31 Jan 2021 05:41:32 +0700 Subject: [PATCH 10/18] Detect Apple M1 on Linux. --- src/backend/cpu/platform/lscpu_arm.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/backend/cpu/platform/lscpu_arm.cpp b/src/backend/cpu/platform/lscpu_arm.cpp index 38d62109..d632ac49 100644 --- a/src/backend/cpu/platform/lscpu_arm.cpp +++ b/src/backend/cpu/platform/lscpu_arm.cpp @@ -208,6 +208,12 @@ static const id_part hisi_part[] = { { -1, nullptr }, }; +static const id_part apple_part[] = { + { 0x022, "M1" }, + { 0x023, "M1" }, + { -1, nullptr }, +}; + static const hw_impl hw_implementer[] = { { 0x41, arm_part, "ARM" }, @@ -221,6 +227,7 @@ static const hw_impl hw_implementer[] = { { 0x51, qcom_part, "Qualcomm" }, { 0x53, samsung_part, "Samsung" }, { 0x56, marvell_part, "Marvell" }, + { 0x61, apple_part, "Apple" }, { 0x66, faraday_part, "Faraday" }, { 0x69, intel_part, "Intel" } }; From 09624c4f9b70c7bd9b73db5b430b68e96305b50a Mon Sep 17 00:00:00 2001 From: XMRig Date: Sun, 31 Jan 2021 23:38:57 +0700 Subject: [PATCH 11/18] Added support for flexible huge page sizes on Linux. --- src/backend/cpu/CpuConfig.cpp | 29 +++++--- src/backend/cpu/CpuConfig.h | 21 +++--- src/core/Controller.cpp | 2 +- src/crypto/common/HugePagesInfo.cpp | 28 ++------ src/crypto/common/HugePagesInfo.h | 10 +-- src/crypto/common/LinuxMemory.cpp | 25 +++---- src/crypto/common/LinuxMemory.h | 6 +- src/crypto/common/VirtualMemory.cpp | 23 +++--- src/crypto/common/VirtualMemory.h | 19 +++-- src/crypto/common/VirtualMemory_unix.cpp | 91 ++++++++++++------------ src/crypto/common/VirtualMemory_win.cpp | 10 +-- 11 files changed, 127 insertions(+), 137 deletions(-) diff --git a/src/backend/cpu/CpuConfig.cpp b/src/backend/cpu/CpuConfig.cpp index 9833a5da..f04038f4 100644 --- a/src/backend/cpu/CpuConfig.cpp +++ b/src/backend/cpu/CpuConfig.cpp @@ -1,12 +1,6 @@ /* 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 2018-2020 SChernykh - * Copyright 2016-2020 XMRig , + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 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 @@ -77,7 +71,7 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const Value obj(kObjectType); obj.AddMember(StringRef(kEnabled), m_enabled, allocator); - obj.AddMember(StringRef(kHugePages), m_hugePages, allocator); + obj.AddMember(StringRef(kHugePages), m_hugePageSize == 0 || m_hugePageSize == kDefaultHugePageSizeKb ? Value(isHugePages()) : Value(m_hugePageSize), allocator); obj.AddMember(StringRef(kHugePagesJit), m_hugePagesJit, allocator); obj.AddMember(StringRef(kHwAes), m_aes == AES_AUTO ? Value(kNullType) : Value(m_aes == AES_HW), allocator); obj.AddMember(StringRef(kPriority), priority() != -1 ? Value(priority()) : Value(kNullType), allocator); @@ -137,14 +131,14 @@ void xmrig::CpuConfig::read(const rapidjson::Value &value) { if (value.IsObject()) { m_enabled = Json::getBool(value, kEnabled, m_enabled); - m_hugePages = Json::getBool(value, kHugePages, m_hugePages); m_hugePagesJit = Json::getBool(value, kHugePagesJit, m_hugePagesJit); m_limit = Json::getUint(value, kMaxThreadsHint, m_limit); m_yield = Json::getBool(value, kYield, m_yield); setAesMode(Json::getValue(value, kHwAes)); - setPriority(Json::getInt(value, kPriority, -1)); + setHugePages(Json::getValue(value, kHugePages)); setMemoryPool(Json::getValue(value, kMemoryPool)); + setPriority(Json::getInt(value, kPriority, -1)); # ifdef XMRIG_FEATURE_ASM m_assembly = Json::getValue(value, kAsm); @@ -218,6 +212,19 @@ void xmrig::CpuConfig::setAesMode(const rapidjson::Value &value) } +void xmrig::CpuConfig::setHugePages(const rapidjson::Value &value) +{ + if (value.IsBool()) { + m_hugePageSize = value.GetBool() ? kDefaultHugePageSizeKb : 0U; + } + else if (value.IsUint()) { + const uint32_t size = value.GetUint(); + + m_hugePageSize = size < kOneGbPageSizeKb ? size : kDefaultHugePageSizeKb; + } +} + + void xmrig::CpuConfig::setMemoryPool(const rapidjson::Value &value) { if (value.IsBool()) { diff --git a/src/backend/cpu/CpuConfig.h b/src/backend/cpu/CpuConfig.h index 95defa67..536c221e 100644 --- a/src/backend/cpu/CpuConfig.h +++ b/src/backend/cpu/CpuConfig.h @@ -1,12 +1,6 @@ /* 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 2018-2020 SChernykh - * Copyright 2016-2020 XMRig , + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 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 @@ -75,8 +69,9 @@ public: std::vector get(const Miner *miner, const Algorithm &algorithm) const; void read(const rapidjson::Value &value); + inline bool astrobwtAVX2() const { return m_astrobwtAVX2; } inline bool isEnabled() const { return m_enabled; } - inline bool isHugePages() const { return m_hugePages; } + inline bool isHugePages() const { return m_hugePageSize > 0; } inline bool isHugePagesJit() const { return m_hugePagesJit; } inline bool isShouldSave() const { return m_shouldSave; } inline bool isYield() const { return m_yield; } @@ -84,13 +79,17 @@ public: inline const String &argon2Impl() const { return m_argon2Impl; } inline const Threads &threads() const { return m_threads; } inline int astrobwtMaxSize() const { return m_astrobwtMaxSize; } - inline bool astrobwtAVX2() const { return m_astrobwtAVX2; } inline int priority() const { return m_priority; } + inline size_t hugePageSize() const { return m_hugePageSize * 1024U; } inline uint32_t limit() const { return m_limit; } private: + constexpr static size_t kDefaultHugePageSizeKb = 2048U; + constexpr static size_t kOneGbPageSizeKb = 1048576U; + void generate(); void setAesMode(const rapidjson::Value &value); + void setHugePages(const rapidjson::Value &value); void setMemoryPool(const rapidjson::Value &value); inline void setPriority(int priority) { m_priority = (priority >= -1 && priority <= 5) ? priority : -1; } @@ -99,13 +98,13 @@ private: Assembly m_assembly; bool m_astrobwtAVX2 = false; bool m_enabled = true; - bool m_hugePages = true; bool m_hugePagesJit = false; bool m_shouldSave = false; bool m_yield = true; int m_astrobwtMaxSize = 550; int m_memoryPool = 0; int m_priority = -1; + size_t m_hugePageSize = kDefaultHugePageSizeKb; String m_argon2Impl; Threads m_threads; uint32_t m_limit = 100; diff --git a/src/core/Controller.cpp b/src/core/Controller.cpp index 40c3aeac..9242b6ee 100644 --- a/src/core/Controller.cpp +++ b/src/core/Controller.cpp @@ -50,7 +50,7 @@ int xmrig::Controller::init() { Base::init(); - VirtualMemory::init(config()->cpu().memPoolSize(), config()->cpu().isHugePages()); + VirtualMemory::init(config()->cpu().memPoolSize(), config()->cpu().hugePageSize()); m_network = std::make_shared(this); diff --git a/src/crypto/common/HugePagesInfo.cpp b/src/crypto/common/HugePagesInfo.cpp index 3108c7de..0a134156 100644 --- a/src/crypto/common/HugePagesInfo.cpp +++ b/src/crypto/common/HugePagesInfo.cpp @@ -1,12 +1,6 @@ /* 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 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 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 @@ -27,24 +21,16 @@ #include "crypto/common/VirtualMemory.h" -namespace xmrig { - -constexpr size_t twoMiB = 2U * 1024U * 1024U; -constexpr size_t oneGiB = 1024U * 1024U * 1024U; - -} // namespace xmrig - - xmrig::HugePagesInfo::HugePagesInfo(const VirtualMemory *memory) { if (memory->isOneGbPages()) { - size = VirtualMemory::align(memory->size(), oneGiB); - total = size / oneGiB; - allocated = size / oneGiB; + size = VirtualMemory::align(memory->size(), VirtualMemory::kOneGiB); + total = size / VirtualMemory::kOneGiB; + allocated = size / VirtualMemory::kOneGiB; } else { - size = memory->size(); - total = size / twoMiB; + size = VirtualMemory::alignToHugePageSize(memory->size()); + total = size / VirtualMemory::hugePageSize(); allocated = memory->isHugePages() ? total : 0; } } diff --git a/src/crypto/common/HugePagesInfo.h b/src/crypto/common/HugePagesInfo.h index 1dc93bb4..295817e3 100644 --- a/src/crypto/common/HugePagesInfo.h +++ b/src/crypto/common/HugePagesInfo.h @@ -1,12 +1,6 @@ /* 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 2018-2019 SChernykh - * Copyright 2016-2019 XMRig , + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 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 diff --git a/src/crypto/common/LinuxMemory.cpp b/src/crypto/common/LinuxMemory.cpp index 297992a2..8a00e1c3 100644 --- a/src/crypto/common/LinuxMemory.cpp +++ b/src/crypto/common/LinuxMemory.cpp @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2020 SChernykh - * Copyright (c) 2016-2020 XMRig , + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 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 @@ -18,8 +18,6 @@ #include "crypto/common/LinuxMemory.h" #include "3rdparty/fmt/core.h" -#include "backend/cpu/Cpu.h" -#include "base/io/log/Log.h" #include "crypto/common/VirtualMemory.h" @@ -37,33 +35,32 @@ constexpr size_t twoMiB = 2U * 1024U * 1024U; constexpr size_t oneGiB = 1024U * 1024U * 1024U; -static inline std::string sysfs_path(uint32_t node, bool oneGbPages, bool nr) +static inline std::string sysfs_path(uint32_t node, size_t hugePageSize, bool nr) { - return fmt::format("/sys/devices/system/node/node{}/hugepages/hugepages-{}kB/{}_hugepages", node, oneGbPages ? "1048576" : "2048", nr ? "nr" : "free"); + return fmt::format("/sys/devices/system/node/node{}/hugepages/hugepages-{}kB/{}_hugepages", node, hugePageSize / 1024, nr ? "nr" : "free"); } -static inline bool write_nr_hugepages(uint32_t node, bool oneGbPages, uint64_t count) { return LinuxMemory::write(sysfs_path(node, oneGbPages, true).c_str(), count); } -static inline int64_t free_hugepages(uint32_t node, bool oneGbPages) { return LinuxMemory::read(sysfs_path(node, oneGbPages, false).c_str()); } -static inline int64_t nr_hugepages(uint32_t node, bool oneGbPages) { return LinuxMemory::read(sysfs_path(node, oneGbPages, true).c_str()); } +static inline bool write_nr_hugepages(uint32_t node, size_t hugePageSize, uint64_t count) { return LinuxMemory::write(sysfs_path(node, hugePageSize, true).c_str(), count); } +static inline int64_t free_hugepages(uint32_t node, size_t hugePageSize) { return LinuxMemory::read(sysfs_path(node, hugePageSize, false).c_str()); } +static inline int64_t nr_hugepages(uint32_t node, size_t hugePageSize) { return LinuxMemory::read(sysfs_path(node, hugePageSize, true).c_str()); } } // namespace xmrig -bool xmrig::LinuxMemory::reserve(size_t size, uint32_t node, bool oneGbPages) +bool xmrig::LinuxMemory::reserve(size_t size, uint32_t node, size_t hugePageSize) { std::lock_guard lock(mutex); - const size_t pageSize = oneGbPages ? oneGiB : twoMiB; - const size_t required = VirtualMemory::align(size, pageSize) / pageSize; + const size_t required = VirtualMemory::align(size, hugePageSize) / hugePageSize; - const auto available = free_hugepages(node, oneGbPages); + const auto available = free_hugepages(node, hugePageSize); if (available < 0 || static_cast(available) >= required) { return false; } - return write_nr_hugepages(node, oneGbPages, std::max(nr_hugepages(node, oneGbPages), 0) + (required - available)); + return write_nr_hugepages(node, hugePageSize, std::max(nr_hugepages(node, hugePageSize), 0) + (required - available)); } diff --git a/src/crypto/common/LinuxMemory.h b/src/crypto/common/LinuxMemory.h index 8f75f00e..0d71af24 100644 --- a/src/crypto/common/LinuxMemory.h +++ b/src/crypto/common/LinuxMemory.h @@ -1,6 +1,6 @@ /* XMRig - * Copyright (c) 2018-2020 SChernykh - * Copyright (c) 2016-2020 XMRig , + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 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 @@ -30,7 +30,7 @@ namespace xmrig { class LinuxMemory { public: - static bool reserve(size_t size, uint32_t node, bool oneGbPages = false); + static bool reserve(size_t size, uint32_t node, size_t hugePageSize); static bool write(const char *path, uint64_t value); static int64_t read(const char *path); diff --git a/src/crypto/common/VirtualMemory.cpp b/src/crypto/common/VirtualMemory.cpp index 7d8d980b..e425750d 100644 --- a/src/crypto/common/VirtualMemory.cpp +++ b/src/crypto/common/VirtualMemory.cpp @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2018-2020 tevador - * Copyright (c) 2018-2020 SChernykh - * Copyright (c) 2016-2020 XMRig , + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 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 @@ -36,16 +36,19 @@ namespace xmrig { -static IMemoryPool *pool = nullptr; + +size_t VirtualMemory::m_hugePageSize = VirtualMemory::kDefaultHugePageSize; +static IMemoryPool *pool = nullptr; static std::mutex mutex; + } // namespace xmrig xmrig::VirtualMemory::VirtualMemory(size_t size, bool hugePages, bool oneGbPages, bool usePool, uint32_t node, size_t alignSize) : - m_size(align(size)), - m_capacity(m_size), - m_node(node) + m_size(alignToHugePageSize(size)), + m_node(node), + m_capacity(m_size) { if (usePool) { std::lock_guard lock(mutex); @@ -114,18 +117,18 @@ void xmrig::VirtualMemory::destroy() } -void xmrig::VirtualMemory::init(size_t poolSize, bool hugePages) +void xmrig::VirtualMemory::init(size_t poolSize, size_t hugePageSize) { if (!pool) { - osInit(hugePages); + osInit(hugePageSize); } # ifdef XMRIG_FEATURE_HWLOC if (Cpu::info()->nodes() > 1) { - pool = new NUMAMemoryPool(align(poolSize, Cpu::info()->nodes()), hugePages); + pool = new NUMAMemoryPool(align(poolSize, Cpu::info()->nodes()), hugePageSize > 0); } else # endif { - pool = new MemoryPool(poolSize, hugePages); + pool = new MemoryPool(poolSize, hugePageSize > 0); } } diff --git a/src/crypto/common/VirtualMemory.h b/src/crypto/common/VirtualMemory.h index e0065e3e..3056cbae 100644 --- a/src/crypto/common/VirtualMemory.h +++ b/src/crypto/common/VirtualMemory.h @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2018-2020 tevador - * Copyright (c) 2018-2020 SChernykh - * Copyright (c) 2016-2020 XMRig , + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 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 @@ -39,6 +39,9 @@ class VirtualMemory public: XMRIG_DISABLE_COPY_MOVE_DEFAULT(VirtualMemory) + constexpr static size_t kDefaultHugePageSize = 2U * 1024U * 1024U; + constexpr static size_t kOneGiB = 1024U * 1024U * 1024U; + VirtualMemory(size_t size, bool hugePages, bool oneGbPages, bool usePool, uint32_t node = 0, size_t alignSize = 64); ~VirtualMemory(); @@ -65,9 +68,11 @@ public: static void destroy(); static void flushInstructionCache(void *p, size_t size); static void freeLargePagesMemory(void *p, size_t size); - static void init(size_t poolSize, bool hugePages); + static void init(size_t poolSize, size_t hugePageSize); - static inline constexpr size_t align(size_t pos, size_t align = 2097152) { return ((pos - 1) / align + 1) * align; } + static inline constexpr size_t align(size_t pos, size_t align = kDefaultHugePageSize) { return ((pos - 1) / align + 1) * align; } + static inline size_t alignToHugePageSize(size_t pos) { return align(pos, hugePageSize()); } + static inline size_t hugePageSize() { return m_hugePageSize; } private: enum Flags { @@ -78,15 +83,17 @@ private: FLAG_MAX }; - static void osInit(bool hugePages); + static void osInit(size_t hugePageSize); bool allocateLargePagesMemory(); bool allocateOneGbPagesMemory(); void freeLargePagesMemory(); + static size_t m_hugePageSize; + const size_t m_size; - size_t m_capacity; const uint32_t m_node; + size_t m_capacity; std::bitset m_flags; uint8_t *m_scratchpad = nullptr; }; diff --git a/src/crypto/common/VirtualMemory_unix.cpp b/src/crypto/common/VirtualMemory_unix.cpp index 60d77cca..5b474841 100644 --- a/src/crypto/common/VirtualMemory_unix.cpp +++ b/src/crypto/common/VirtualMemory_unix.cpp @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2018-2020 tevador - * Copyright (c) 2018-2020 SChernykh - * Copyright (c) 2016-2020 XMRig , + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 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 @@ -18,13 +18,14 @@ */ -#include -#include - - +#include "crypto/common/VirtualMemory.h" #include "backend/cpu/Cpu.h" #include "crypto/common/portable/mm_malloc.h" -#include "crypto/common/VirtualMemory.h" + + +#include +#include +#include #ifdef XMRIG_OS_APPLE @@ -42,14 +43,21 @@ #endif -#if defined(XMRIG_OS_LINUX) -# if (defined(MAP_HUGE_1GB) || defined(MAP_HUGE_SHIFT)) -# define XMRIG_HAS_1GB_PAGES -# endif +#ifdef XMRIG_OS_LINUX # include "crypto/common/LinuxMemory.h" #endif +#ifndef MAP_HUGE_SHIFT +# define MAP_HUGE_SHIFT 26 +#endif + + +#ifndef MAP_HUGE_MASK +# define MAP_HUGE_MASK 0x3f +#endif + + #ifdef XMRIG_SECURE_JIT # define SECURE_PROT_EXEC 0 #else @@ -57,6 +65,18 @@ #endif +namespace xmrig { + + +static inline int hugePagesFlag(size_t size) +{ + return (static_cast(log2(size)) & MAP_HUGE_MASK) << MAP_HUGE_SHIFT; +} + + +} // namespace xmrig + + bool xmrig::VirtualMemory::isHugepagesAvailable() { # if defined(XMRIG_OS_MACOS) && defined(XMRIG_ARM) @@ -69,7 +89,7 @@ bool xmrig::VirtualMemory::isHugepagesAvailable() bool xmrig::VirtualMemory::isOneGbPagesAvailable() { -# ifdef XMRIG_HAS_1GB_PAGES +# ifdef XMRIG_OS_LINUX return Cpu::info()->hasOneGbPages(); # else return false; @@ -126,18 +146,10 @@ void *xmrig::VirtualMemory::allocateExecutableMemory(size_t size, bool hugePages # else -# if defined(MAP_HUGE_2MB) - constexpr int flag_2mb = MAP_HUGE_2MB; -# elif defined(MAP_HUGE_SHIFT) - constexpr int flag_2mb = (21 << MAP_HUGE_SHIFT); -# else - constexpr int flag_2mb = 0; -# endif - void *mem = nullptr; if (hugePages) { - mem = mmap(0, align(size), PROT_READ | PROT_WRITE | SECURE_PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE | flag_2mb, -1, 0); + mem = mmap(0, align(size), PROT_READ | PROT_WRITE | SECURE_PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE | hugePagesFlag(hugePageSize()), -1, 0); } if (!mem) { @@ -157,17 +169,7 @@ void *xmrig::VirtualMemory::allocateLargePagesMemory(size_t size) # elif defined(__FreeBSD__) void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0); # else - -# if defined(MAP_HUGE_2MB) - constexpr int flag_2mb = MAP_HUGE_2MB; -# elif defined(MAP_HUGE_SHIFT) - constexpr int flag_2mb = (21 << MAP_HUGE_SHIFT); -# else - constexpr int flag_2mb = 0; -# endif - - void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE | flag_2mb, 0, 0); - + void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE | hugePagesFlag(hugePageSize()), 0, 0); # endif return mem == MAP_FAILED ? nullptr : mem; @@ -176,17 +178,9 @@ void *xmrig::VirtualMemory::allocateLargePagesMemory(size_t size) void *xmrig::VirtualMemory::allocateOneGbPagesMemory(size_t size) { -# ifdef XMRIG_HAS_1GB_PAGES +# ifdef XMRIG_OS_LINUX if (isOneGbPagesAvailable()) { -# if defined(MAP_HUGE_1GB) - constexpr int flag_1gb = MAP_HUGE_1GB; -# elif defined(MAP_HUGE_SHIFT) - constexpr int flag_1gb = (30 << MAP_HUGE_SHIFT); -# else - constexpr int flag_1gb = 0; -# endif - - void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE | flag_1gb, 0, 0); + void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE | hugePagesFlag(kOneGiB), 0, 0); return mem == MAP_FAILED ? nullptr : mem; } @@ -212,15 +206,18 @@ void xmrig::VirtualMemory::freeLargePagesMemory(void *p, size_t size) } -void xmrig::VirtualMemory::osInit(bool) +void xmrig::VirtualMemory::osInit(size_t hugePageSize) { + if (hugePageSize) { + m_hugePageSize = hugePageSize; + } } bool xmrig::VirtualMemory::allocateLargePagesMemory() { -# if defined(XMRIG_OS_LINUX) - LinuxMemory::reserve(m_size, m_node); +# ifdef XMRIG_OS_LINUX + LinuxMemory::reserve(m_size, m_node, hugePageSize()); # endif m_scratchpad = static_cast(allocateLargePagesMemory(m_size)); @@ -242,8 +239,8 @@ bool xmrig::VirtualMemory::allocateLargePagesMemory() bool xmrig::VirtualMemory::allocateOneGbPagesMemory() { -# if defined(XMRIG_HAS_1GB_PAGES) - LinuxMemory::reserve(m_size, m_node, true); +# ifdef XMRIG_OS_LINUX + LinuxMemory::reserve(m_size, m_node, kOneGiB); # endif m_scratchpad = static_cast(allocateOneGbPagesMemory(m_size)); diff --git a/src/crypto/common/VirtualMemory_win.cpp b/src/crypto/common/VirtualMemory_win.cpp index fee5f585..acf8119f 100644 --- a/src/crypto/common/VirtualMemory_win.cpp +++ b/src/crypto/common/VirtualMemory_win.cpp @@ -1,7 +1,7 @@ /* XMRig * Copyright (c) 2018-2020 tevador - * Copyright (c) 2018-2020 SChernykh - * Copyright (c) 2016-2020 XMRig , + * Copyright (c) 2018-2021 SChernykh + * Copyright (c) 2016-2021 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 @@ -24,9 +24,9 @@ #include +#include "crypto/common/VirtualMemory.h" #include "base/io/log/Log.h" #include "crypto/common/portable/mm_malloc.h" -#include "crypto/common/VirtualMemory.h" #ifdef XMRIG_SECURE_JIT @@ -233,9 +233,9 @@ void xmrig::VirtualMemory::freeLargePagesMemory(void *p, size_t) } -void xmrig::VirtualMemory::osInit(bool hugePages) +void xmrig::VirtualMemory::osInit(size_t hugePageSize) { - if (hugePages) { + if (hugePageSize) { hugepagesAvailable = TrySetLockPagesPrivilege(); } } From 4c3425a958eac4321a10778c153a125cc6e3ea03 Mon Sep 17 00:00:00 2001 From: XMRig Date: Mon, 1 Feb 2021 05:06:24 +0700 Subject: [PATCH 12/18] Added "--hugepage-size" command line option. --- src/base/kernel/interfaces/IConfig.h | 1 + src/core/config/ConfigTransform.cpp | 10 +++++++--- src/core/config/Config_platform.h | 2 ++ src/core/config/usage.h | 5 ++++- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/base/kernel/interfaces/IConfig.h b/src/base/kernel/interfaces/IConfig.h index 792c43a1..ba022fa3 100644 --- a/src/base/kernel/interfaces/IConfig.h +++ b/src/base/kernel/interfaces/IConfig.h @@ -85,6 +85,7 @@ public: BenchHashKey = 1047, BenchTokenKey = 1048, DmiKey = 1049, + HugePageSizeKey = 1050, // xmrig common CPUPriorityKey = 1021, diff --git a/src/core/config/ConfigTransform.cpp b/src/core/config/ConfigTransform.cpp index 10f819e4..7140837a 100644 --- a/src/core/config/ConfigTransform.cpp +++ b/src/core/config/ConfigTransform.cpp @@ -125,9 +125,10 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const BaseTransform::transform(doc, key, arg); switch (key) { - case IConfig::AVKey: /* --av */ - case IConfig::CPUPriorityKey: /* --cpu-priority */ - case IConfig::ThreadsKey: /* --threads */ + case IConfig::AVKey: /* --av */ + case IConfig::CPUPriorityKey: /* --cpu-priority */ + case IConfig::ThreadsKey: /* --threads */ + case IConfig::HugePageSizeKey: /* --hugepage-size */ return transformUint64(doc, key, static_cast(strtol(arg, nullptr, 10))); case IConfig::HugePagesKey: /* --no-huge-pages */ @@ -306,6 +307,9 @@ void xmrig::ConfigTransform::transformUint64(rapidjson::Document &doc, int key, case IConfig::CPUPriorityKey: /* --cpu-priority */ return set(doc, CpuConfig::kField, CpuConfig::kPriority, arg); + case IConfig::HugePageSizeKey: /* --hugepage-size */ + return set(doc, CpuConfig::kField, CpuConfig::kHugePages, arg); + default: break; } diff --git a/src/core/config/Config_platform.h b/src/core/config/Config_platform.h index b6fcd1c1..28b1e2bd 100644 --- a/src/core/config/Config_platform.h +++ b/src/core/config/Config_platform.h @@ -71,6 +71,8 @@ static const option options[] = { { "nicehash", 0, nullptr, IConfig::NicehashKey }, { "no-color", 0, nullptr, IConfig::ColorKey }, { "no-huge-pages", 0, nullptr, IConfig::HugePagesKey }, + { "no-hugepages", 0, nullptr, IConfig::HugePagesKey }, + { "hugepage-size", 1, nullptr, IConfig::HugePageSizeKey }, { "pass", 1, nullptr, IConfig::PasswordKey }, { "print-time", 1, nullptr, IConfig::PrintTimeKey }, { "retries", 1, nullptr, IConfig::RetriesKey }, diff --git a/src/core/config/usage.h b/src/core/config/usage.h index 261e571c..a30ea133 100644 --- a/src/core/config/usage.h +++ b/src/core/config/usage.h @@ -83,6 +83,9 @@ static inline const std::string &usage() u += " --cpu-memory-pool=N number of 2 MB pages for persistent memory pool, -1 (auto), 0 (disable)\n"; u += " --cpu-no-yield prefer maximum hashrate rather than system response/stability\n"; u += " --no-huge-pages disable huge pages support\n"; +# ifdef XMRIG_OS_LINUX + u += " --hugepage-size=N custom hugepage size in kB\n"; +# endif u += " --asm=ASM ASM optimizations, possible values: auto, none, intel, ryzen, bulldozer\n"; # if defined(__x86_64__) || defined(_M_AMD64) @@ -155,7 +158,7 @@ static inline const std::string &usage() u += " -l, --log-file=FILE log all output to a file\n"; u += " --print-time=N print hashrate report every N seconds\n"; -# ifdef XMRIG_FEATURE_NVML +# if defined(XMRIG_FEATURE_NVML) || defined(XMRIG_FEATURE_ADL) u += " --health-print-time=N print health report every N seconds\n"; # endif u += " --no-color disable colored output\n"; From 4108428872e916f1a62cac7cb82cbfc18dbcaaba Mon Sep 17 00:00:00 2001 From: SChernykh Date: Mon, 1 Feb 2021 17:07:45 +0100 Subject: [PATCH 13/18] Fixed crashes on ARM --- src/crypto/randomx/jit_compiler_a64.cpp | 6 +++--- src/crypto/rx/RxConfig.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/crypto/randomx/jit_compiler_a64.cpp b/src/crypto/randomx/jit_compiler_a64.cpp index f98e36f6..da1d2471 100644 --- a/src/crypto/randomx/jit_compiler_a64.cpp +++ b/src/crypto/randomx/jit_compiler_a64.cpp @@ -171,7 +171,7 @@ void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& con emit32(ARMV8A::EOR | 10 | (IntRegMap[config.readReg0] << 5) | (IntRegMap[config.readReg1] << 16), code, codePos); # ifndef XMRIG_OS_APPLE - xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast(code + MainLoopBegin), reinterpret_cast(code + codePos)); + xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast(code + MainLoopBegin), codePos - MainLoopBegin); # endif } @@ -237,7 +237,7 @@ void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration emit32(ARMV8A::ADD_IMM_HI | 2 | (2 << 5) | (imm_hi << 10), code, codePos); # ifndef XMRIG_OS_APPLE - xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast(code + MainLoopBegin), reinterpret_cast(code + codePos)); + xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast(code + MainLoopBegin), codePos - MainLoopBegin); # endif } @@ -364,7 +364,7 @@ void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[N]) codePos += p2 - p1; # ifndef XMRIG_OS_APPLE - xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast(code + CodeSize), reinterpret_cast(code + codePos)); + xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast(code + CodeSize), codePos - MainLoopBegin); # endif } diff --git a/src/crypto/rx/RxConfig.h b/src/crypto/rx/RxConfig.h index 78d2f964..ea1bf685 100644 --- a/src/crypto/rx/RxConfig.h +++ b/src/crypto/rx/RxConfig.h @@ -113,7 +113,6 @@ private: Mode readMode(const rapidjson::Value &value) const; - bool m_numa = true; bool m_oneGbPages = false; bool m_rdmsr = true; int m_threads = -1; @@ -123,6 +122,7 @@ private: ScratchpadPrefetchMode m_scratchpadPrefetchMode = ScratchpadPrefetchT0; # ifdef XMRIG_FEATURE_HWLOC + bool m_numa = true; std::vector m_nodeset; # endif From e74573f81f1b38b4e606b52c39165737656c7f57 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Mon, 1 Feb 2021 22:36:11 +0100 Subject: [PATCH 14/18] Fixed code allocation for ARM --- src/crypto/randomx/jit_compiler_a64.cpp | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/crypto/randomx/jit_compiler_a64.cpp b/src/crypto/randomx/jit_compiler_a64.cpp index da1d2471..fda829be 100644 --- a/src/crypto/randomx/jit_compiler_a64.cpp +++ b/src/crypto/randomx/jit_compiler_a64.cpp @@ -108,6 +108,7 @@ JitCompilerA64::JitCompilerA64(bool hugePagesEnable, bool) : hugePages(hugePagesJIT && hugePagesEnable), literalPos(ImulRcpLiteralsEnd) { + allocate(CodeSize); } JitCompilerA64::~JitCompilerA64() @@ -117,13 +118,8 @@ JitCompilerA64::~JitCompilerA64() void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& config, uint32_t) { - if (!allocatedSize) { - allocate(CodeSize); - } #ifdef XMRIG_SECURE_JIT - else { - enableWriting(); - } + enableWriting(); #endif uint32_t codePos = MainLoopBegin + 4; @@ -177,13 +173,8 @@ void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& con void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration& config, uint32_t datasetOffset) { - if (!allocatedSize) { - allocate(CodeSize); - } #ifdef XMRIG_SECURE_JIT - else { - enableWriting(); - } + enableWriting(); #endif uint32_t codePos = MainLoopBegin + 4; @@ -244,8 +235,12 @@ void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration template void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[N]) { - if (!allocatedSize) { - allocate(CodeSize + CalcDatasetItemSize()); + const size_t requiredSize = CodeSize + CalcDatasetItemSize(); + if (allocatedSize < requiredSize) { + if (allocatedSize) { + freePagedMemory(code, allocatedSize); + } + allocate(requiredSize); } #ifdef XMRIG_SECURE_JIT else { From db035738046aab3f4edfbe2d17acf297b691b4ac Mon Sep 17 00:00:00 2001 From: SChernykh Date: Mon, 1 Feb 2021 22:42:35 +0100 Subject: [PATCH 15/18] ARM JIT: added missing cache flush --- src/crypto/randomx/jit_compiler_a64.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/crypto/randomx/jit_compiler_a64.cpp b/src/crypto/randomx/jit_compiler_a64.cpp index fda829be..5c8bbea2 100644 --- a/src/crypto/randomx/jit_compiler_a64.cpp +++ b/src/crypto/randomx/jit_compiler_a64.cpp @@ -396,6 +396,10 @@ void JitCompilerA64::allocate(size_t size) code = static_cast(allocExecutableMemory(allocatedSize, hugePages)); memcpy(code, reinterpret_cast(randomx_program_aarch64), CodeSize); + +# ifndef XMRIG_OS_APPLE + xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast(code), CodeSize); +# endif } From 346892e17059888421ee782d3ecb6f263595b773 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Mon, 1 Feb 2021 22:52:02 +0100 Subject: [PATCH 16/18] Update jit_compiler_a64.cpp --- src/crypto/randomx/jit_compiler_a64.cpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/crypto/randomx/jit_compiler_a64.cpp b/src/crypto/randomx/jit_compiler_a64.cpp index 5c8bbea2..c4f0f002 100644 --- a/src/crypto/randomx/jit_compiler_a64.cpp +++ b/src/crypto/randomx/jit_compiler_a64.cpp @@ -108,7 +108,6 @@ JitCompilerA64::JitCompilerA64(bool hugePagesEnable, bool) : hugePages(hugePagesJIT && hugePagesEnable), literalPos(ImulRcpLiteralsEnd) { - allocate(CodeSize); } JitCompilerA64::~JitCompilerA64() @@ -118,8 +117,13 @@ JitCompilerA64::~JitCompilerA64() void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& config, uint32_t) { + if (!allocatedSize) { + allocate(CodeSize); + } #ifdef XMRIG_SECURE_JIT - enableWriting(); + else { + enableWriting(); + } #endif uint32_t codePos = MainLoopBegin + 4; @@ -173,8 +177,13 @@ void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& con void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration& config, uint32_t datasetOffset) { + if (!allocatedSize) { + allocate(CodeSize); + } #ifdef XMRIG_SECURE_JIT - enableWriting(); + else { + enableWriting(); + } #endif uint32_t codePos = MainLoopBegin + 4; @@ -235,12 +244,8 @@ void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration template void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[N]) { - const size_t requiredSize = CodeSize + CalcDatasetItemSize(); - if (allocatedSize < requiredSize) { - if (allocatedSize) { - freePagedMemory(code, allocatedSize); - } - allocate(requiredSize); + if (!allocatedSize) { + allocate(CodeSize + CalcDatasetItemSize()); } #ifdef XMRIG_SECURE_JIT else { From 2c8d8ee2ab93f22eec937f58667df7502a4f5499 Mon Sep 17 00:00:00 2001 From: XMRig Date: Tue, 2 Feb 2021 13:53:45 +0700 Subject: [PATCH 17/18] Fixed macOS build and compile warning. --- src/backend/cpu/CpuConfig.cpp | 2 +- src/crypto/common/VirtualMemory_unix.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/backend/cpu/CpuConfig.cpp b/src/backend/cpu/CpuConfig.cpp index f04038f4..3f743040 100644 --- a/src/backend/cpu/CpuConfig.cpp +++ b/src/backend/cpu/CpuConfig.cpp @@ -71,7 +71,7 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const Value obj(kObjectType); obj.AddMember(StringRef(kEnabled), m_enabled, allocator); - obj.AddMember(StringRef(kHugePages), m_hugePageSize == 0 || m_hugePageSize == kDefaultHugePageSizeKb ? Value(isHugePages()) : Value(m_hugePageSize), allocator); + obj.AddMember(StringRef(kHugePages), m_hugePageSize == 0 || m_hugePageSize == kDefaultHugePageSizeKb ? Value(isHugePages()) : Value(static_cast(m_hugePageSize)), allocator); obj.AddMember(StringRef(kHugePagesJit), m_hugePagesJit, allocator); obj.AddMember(StringRef(kHwAes), m_aes == AES_AUTO ? Value(kNullType) : Value(m_aes == AES_HW), allocator); obj.AddMember(StringRef(kPriority), priority() != -1 ? Value(priority()) : Value(kNullType), allocator); diff --git a/src/crypto/common/VirtualMemory_unix.cpp b/src/crypto/common/VirtualMemory_unix.cpp index 5b474841..e3362bc1 100644 --- a/src/crypto/common/VirtualMemory_unix.cpp +++ b/src/crypto/common/VirtualMemory_unix.cpp @@ -68,11 +68,12 @@ namespace xmrig { +#ifdef XMRIG_OS_LINUX static inline int hugePagesFlag(size_t size) { return (static_cast(log2(size)) & MAP_HUGE_MASK) << MAP_HUGE_SHIFT; } - +#endif } // namespace xmrig From a4af96469659c9b93d08ead7779e3a5d489224e4 Mon Sep 17 00:00:00 2001 From: xmrig Date: Wed, 3 Feb 2021 06:04:30 +0700 Subject: [PATCH 18/18] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9f51507..b6dedbcf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# v6.8.1 +- [#2064](https://github.com/xmrig/xmrig/pull/2064) Added documentation for config.json CPU options. +- [#2066](https://github.com/xmrig/xmrig/issues/2066) Fixed AMD GPUs health data readings on Linux. +- [#2067](https://github.com/xmrig/xmrig/pull/2067) Fixed compilation error when RandomX and Argon2 are disabled. +- [#2076](https://github.com/xmrig/xmrig/pull/2076) Added support for flexible huge page sizes on Linux. +- [#2077](https://github.com/xmrig/xmrig/pull/2077) Fixed `illegal instruction` crash on ARM. + # v6.8.0 - [#2052](https://github.com/xmrig/xmrig/pull/2052) Added DMI/SMBIOS reader. - Added information about memory modules on the miner startup and for online benchmark.