diff --git a/CHANGELOG.md b/CHANGELOG.md index d70d0fc73..f43e11974 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# v5.1.1 +- [#1365](https://github.com/xmrig/xmrig/issues/1365) Fixed various system response/stability issues. + - Added new CPU option `yield` and command line equivalent `--cpu-no-yield`. +- [#1363](https://github.com/xmrig/xmrig/issues/1363) Fixed wrong priority of main miner thread. + # v5.1.0 - [#1351](https://github.com/xmrig/xmrig/pull/1351) RandomX optimizations and fixes. - Improved RandomX performance (up to +6-7% on Intel CPUs, +2-3% on Ryzen CPUs) diff --git a/README.md b/README.md index 6b7ce909e..7563ff2d9 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ CPU backend: --cpu-priority set process priority (0 idle, 2 normal to 5 highest) --cpu-max-threads-hint=N maximum CPU threads count (in percentage) hint for autoconfig --cpu-memory-pool=N number of 2 MB pages for persistent memory pool, -1 (auto), 0 (disable) + --cpu-no-yield prefer maximum hashrate rather than system response/stability --no-huge-pages disable huge pages support --asm=ASM ASM optimizations, possible values: auto, none, intel, ryzen, bulldozer --randomx-init=N threads count to initialize RandomX dataset diff --git a/doc/CPU.md b/doc/CPU.md index c830590f4..385af6ad5 100644 --- a/doc/CPU.md +++ b/doc/CPU.md @@ -99,4 +99,7 @@ Allow override automatically detected Argon2 implementation, this option added m 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. Default value `false` (feature disabled) or `true` or specific count of 2 MB huge pages. +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`. diff --git a/src/App.cpp b/src/App.cpp index 1908482c1..3acccc5df 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -90,8 +90,6 @@ int xmrig::App::exec() m_controller->start(); - Platform::setThreadPriority(5); - rc = uv_run(uv_default_loop(), UV_RUN_DEFAULT); uv_loop_close(uv_default_loop()); diff --git a/src/backend/common/Hashrate.cpp b/src/backend/common/Hashrate.cpp index dedb74955..eb01a5fb0 100644 --- a/src/backend/common/Hashrate.cpp +++ b/src/backend/common/Hashrate.cpp @@ -30,6 +30,7 @@ #include "backend/common/Hashrate.h" +#include "base/io/json/Json.h" #include "base/tools/Chrono.h" #include "base/tools/Handle.h" #include "rapidjson/document.h" @@ -157,13 +158,7 @@ const char *xmrig::Hashrate::format(double h, char *buf, size_t size) rapidjson::Value xmrig::Hashrate::normalize(double d) { - using namespace rapidjson; - - if (!std::isnormal(d)) { - return Value(kNullType); - } - - return Value(floor(d * 100.0) / 100.0); + return Json::normalize(d, false); } diff --git a/src/backend/cpu/CpuConfig.cpp b/src/backend/cpu/CpuConfig.cpp index e9abd9e66..7ebe904bd 100644 --- a/src/backend/cpu/CpuConfig.cpp +++ b/src/backend/cpu/CpuConfig.cpp @@ -38,6 +38,7 @@ static const char *kHwAes = "hw-aes"; static const char *kMaxThreadsHint = "max-threads-hint"; static const char *kMemoryPool = "memory-pool"; static const char *kPriority = "priority"; +static const char *kYield = "yield"; #ifdef XMRIG_FEATURE_ASM static const char *kAsm = "asm"; @@ -70,6 +71,7 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const 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); obj.AddMember(StringRef(kMemoryPool), m_memoryPool < 1 ? Value(m_memoryPool < 0) : Value(m_memoryPool), allocator); + obj.AddMember(StringRef(kYield), m_yield, allocator); if (m_threads.isEmpty()) { obj.AddMember(StringRef(kMaxThreadsHint), m_limit, allocator); @@ -120,6 +122,7 @@ void xmrig::CpuConfig::read(const rapidjson::Value &value) m_enabled = Json::getBool(value, kEnabled, m_enabled); m_hugePages = Json::getBool(value, kHugePages, m_hugePages); 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)); diff --git a/src/backend/cpu/CpuConfig.h b/src/backend/cpu/CpuConfig.h index fa48e07bf..2306057fc 100644 --- a/src/backend/cpu/CpuConfig.h +++ b/src/backend/cpu/CpuConfig.h @@ -55,6 +55,7 @@ public: inline bool isEnabled() const { return m_enabled; } inline bool isHugePages() const { return m_hugePages; } inline bool isShouldSave() const { return m_shouldSave; } + inline bool isYield() const { return m_yield; } inline const Assembly &assembly() const { return m_assembly; } inline const String &argon2Impl() const { return m_argon2Impl; } inline const Threads &threads() const { return m_threads; } @@ -72,6 +73,7 @@ private: bool m_enabled = true; bool m_hugePages = true; bool m_shouldSave = false; + bool m_yield = true; int m_memoryPool = 0; int m_priority = -1; String m_argon2Impl; diff --git a/src/backend/cpu/CpuLaunchData.cpp b/src/backend/cpu/CpuLaunchData.cpp index bbfc6bba9..76da267c1 100644 --- a/src/backend/cpu/CpuLaunchData.cpp +++ b/src/backend/cpu/CpuLaunchData.cpp @@ -38,6 +38,7 @@ xmrig::CpuLaunchData::CpuLaunchData(const Miner *miner, const Algorithm &algorit assembly(config.assembly()), hugePages(config.isHugePages()), hwAES(config.isHwAES()), + yield(config.isYield()), priority(config.priority()), affinity(thread.affinity()), miner(miner), diff --git a/src/backend/cpu/CpuLaunchData.h b/src/backend/cpu/CpuLaunchData.h index 586738447..6a1ee30e4 100644 --- a/src/backend/cpu/CpuLaunchData.h +++ b/src/backend/cpu/CpuLaunchData.h @@ -60,6 +60,7 @@ public: const Assembly assembly; const bool hugePages; const bool hwAES; + const bool yield; const int priority; const int64_t affinity; const Miner *miner; diff --git a/src/backend/cpu/CpuWorker.cpp b/src/backend/cpu/CpuWorker.cpp index 7584b6867..2e223a31e 100644 --- a/src/backend/cpu/CpuWorker.cpp +++ b/src/backend/cpu/CpuWorker.cpp @@ -58,6 +58,7 @@ xmrig::CpuWorker::CpuWorker(size_t id, const CpuLaunchData &data) : m_algorithm(data.algorithm), m_assembly(data.assembly), m_hwAES(data.hwAES), + m_yield(data.yield), m_av(data.av()), m_miner(data.miner), m_ctx() @@ -236,6 +237,10 @@ void xmrig::CpuWorker::start() } m_count += N; + + if (m_yield) { + std::this_thread::yield(); + } } consumeJob(); diff --git a/src/backend/cpu/CpuWorker.h b/src/backend/cpu/CpuWorker.h index 31819de97..11aba0478 100644 --- a/src/backend/cpu/CpuWorker.h +++ b/src/backend/cpu/CpuWorker.h @@ -71,6 +71,7 @@ private: const Algorithm m_algorithm; const Assembly m_assembly; const bool m_hwAES; + const bool m_yield; const CnHash::AlgoVariant m_av; const Miner *m_miner; cryptonight_ctx *m_ctx[N]; diff --git a/src/base/api/Api.cpp b/src/base/api/Api.cpp index c66241c9c..c4b2c5a7d 100644 --- a/src/base/api/Api.cpp +++ b/src/base/api/Api.cpp @@ -31,10 +31,11 @@ #endif -#include "3rdparty/http-parser/http_parser.h" #include "base/api/Api.h" +#include "3rdparty/http-parser/http_parser.h" #include "base/api/interfaces/IApiListener.h" #include "base/api/requests/HttpApiRequest.h" +#include "base/io/json/Json.h" #include "base/kernel/Base.h" #include "base/tools/Buffer.h" #include "base/tools/Chrono.h" @@ -73,9 +74,10 @@ static rapidjson::Value getResources(rapidjson::Document &doc) double loadavg[3] = { 0.0 }; uv_loadavg(loadavg); - load_average.PushBack(loadavg[0], allocator); - load_average.PushBack(loadavg[1], allocator); - load_average.PushBack(loadavg[2], allocator); + + for (double value : loadavg) { + load_average.PushBack(Json::normalize(value, true), allocator); + } out.AddMember("memory", memory, allocator); out.AddMember("load_average", load_average, allocator); @@ -182,6 +184,9 @@ void xmrig::Api::exec(IApiRequest &request) # endif # ifdef XMRIG_FEATURE_OPENCL features.PushBack("opencl", allocator); +# endif +# ifdef XMRIG_FEATURE_CUDA + features.PushBack("cuda", allocator); # endif reply.AddMember("features", features, allocator); } diff --git a/src/base/io/json/Json.cpp b/src/base/io/json/Json.cpp index 9a5782933..738621448 100644 --- a/src/base/io/json/Json.cpp +++ b/src/base/io/json/Json.cpp @@ -28,6 +28,7 @@ #include +#include namespace xmrig { @@ -154,6 +155,18 @@ unsigned xmrig::Json::getUint(const rapidjson::Value &obj, const char *key, unsi } +rapidjson::Value xmrig::Json::normalize(double value, bool zero) +{ + using namespace rapidjson; + + if (!std::isnormal(value)) { + return zero ? Value(0.0) : Value(kNullType); + } + + return Value(floor(value * 100.0) / 100.0); +} + + bool xmrig::JsonReader::isEmpty() const { return !m_obj.IsObject() || m_obj.ObjectEmpty(); diff --git a/src/base/io/json/Json.h b/src/base/io/json/Json.h index 80fe5dc26..b5e2a3c8a 100644 --- a/src/base/io/json/Json.h +++ b/src/base/io/json/Json.h @@ -48,6 +48,8 @@ public: static bool get(const char *fileName, rapidjson::Document &doc); static bool save(const char *fileName, const rapidjson::Document &doc); + + static rapidjson::Value normalize(double value, bool zero); }; diff --git a/src/base/kernel/Base.cpp b/src/base/kernel/Base.cpp index 90c7cb57c..5718a115e 100644 --- a/src/base/kernel/Base.cpp +++ b/src/base/kernel/Base.cpp @@ -176,10 +176,6 @@ int xmrig::Base::init() Platform::init(config()->userAgent()); -# ifndef XMRIG_PROXY_PROJECT - Platform::setProcessPriority(config()->cpu().priority()); -# endif - if (isBackground()) { Log::background = true; } diff --git a/src/base/kernel/Platform.h b/src/base/kernel/Platform.h index 3f026f8bd..fe39a69ea 100644 --- a/src/base/kernel/Platform.h +++ b/src/base/kernel/Platform.h @@ -51,7 +51,6 @@ public: static uint32_t setTimerResolution(uint32_t resolution); static void init(const char *userAgent); static void restoreTimerResolution(); - static void setProcessPriority(int priority); static void setThreadPriority(int priority); static inline const char *userAgent() { return m_userAgent; } diff --git a/src/base/kernel/Platform_mac.cpp b/src/base/kernel/Platform_mac.cpp index 146dd52d7..8d9bac3b8 100644 --- a/src/base/kernel/Platform_mac.cpp +++ b/src/base/kernel/Platform_mac.cpp @@ -83,11 +83,6 @@ void xmrig::Platform::restoreTimerResolution() } -void xmrig::Platform::setProcessPriority(int priority) -{ -} - - void xmrig::Platform::setThreadPriority(int priority) { if (priority == -1) { diff --git a/src/base/kernel/Platform_unix.cpp b/src/base/kernel/Platform_unix.cpp index bbba39f90..b6ca17e4a 100644 --- a/src/base/kernel/Platform_unix.cpp +++ b/src/base/kernel/Platform_unix.cpp @@ -111,11 +111,6 @@ void xmrig::Platform::restoreTimerResolution() } -void xmrig::Platform::setProcessPriority(int priority) -{ -} - - void xmrig::Platform::setThreadPriority(int priority) { if (priority == -1) { diff --git a/src/base/kernel/Platform_win.cpp b/src/base/kernel/Platform_win.cpp index 064c8352f..ad93cb6a7 100644 --- a/src/base/kernel/Platform_win.cpp +++ b/src/base/kernel/Platform_win.cpp @@ -131,43 +131,6 @@ void xmrig::Platform::restoreTimerResolution() } -void xmrig::Platform::setProcessPriority(int priority) -{ - if (priority == -1) { - return; - } - - DWORD prio = IDLE_PRIORITY_CLASS; - switch (priority) - { - case 1: - prio = BELOW_NORMAL_PRIORITY_CLASS; - break; - - case 2: - prio = NORMAL_PRIORITY_CLASS; - break; - - case 3: - prio = ABOVE_NORMAL_PRIORITY_CLASS; - break; - - case 4: - prio = HIGH_PRIORITY_CLASS; - break; - - case 5: - prio = REALTIME_PRIORITY_CLASS; - break; - - default: - break; - } - - SetPriorityClass(GetCurrentProcess(), prio); -} - - void xmrig::Platform::setThreadPriority(int priority) { if (priority == -1) { diff --git a/src/base/kernel/interfaces/IConfig.h b/src/base/kernel/interfaces/IConfig.h index 5044545a5..dbbf82cd9 100644 --- a/src/base/kernel/interfaces/IConfig.h +++ b/src/base/kernel/interfaces/IConfig.h @@ -92,6 +92,7 @@ public: RandomXModeKey = 1029, CPUMaxThreadsKey = 1026, MemoryPoolKey = 1027, + YieldKey = 1030, // xmrig amd OclPlatformKey = 1400, diff --git a/src/config.json b/src/config.json index fbbf8225b..df366c0ff 100644 --- a/src/config.json +++ b/src/config.json @@ -25,6 +25,7 @@ "hw-aes": null, "priority": null, "memory-pool": false, + "yield": true, "max-threads-hint": 100, "asm": true, "argon2-impl": null, diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index 20ff3fd73..5551268a6 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -263,6 +263,11 @@ public: xmrig::Miner::Miner(Controller *controller) : d_ptr(new MinerPrivate(controller)) { + const int priority = controller->config()->cpu().priority(); + if (priority >= 0) { + Platform::setThreadPriority(std::min(priority + 1, 5)); + } + # ifdef XMRIG_ALGO_RANDOMX Rx::init(this); # endif diff --git a/src/core/config/ConfigTransform.cpp b/src/core/config/ConfigTransform.cpp index 667d91174..b9f666789 100644 --- a/src/core/config/ConfigTransform.cpp +++ b/src/core/config/ConfigTransform.cpp @@ -147,7 +147,9 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const case IConfig::MemoryPoolKey: /* --cpu-memory-pool */ return set(doc, kCpu, "memory-pool", static_cast(strtol(arg, nullptr, 10))); - break; + + case IConfig::YieldKey: /* --cpu-no-yield */ + return set(doc, kCpu, "yield", false); # ifdef XMRIG_FEATURE_ASM case IConfig::AssemblyKey: /* --asm */ diff --git a/src/core/config/Config_default.h b/src/core/config/Config_default.h index afd3638bb..3db93a82f 100644 --- a/src/core/config/Config_default.h +++ b/src/core/config/Config_default.h @@ -50,6 +50,7 @@ R"===( "colors": true, "randomx": { "init": -1, + "mode": "auto", "numa": true }, "cpu": { @@ -58,6 +59,7 @@ R"===( "hw-aes": null, "priority": null, "memory-pool": false, + "yield": true, "max-threads-hint": 100, "asm": true, "argon2-impl": null, diff --git a/src/core/config/Config_platform.h b/src/core/config/Config_platform.h index 608ac48ee..a866c128c 100644 --- a/src/core/config/Config_platform.h +++ b/src/core/config/Config_platform.h @@ -86,6 +86,7 @@ static const option options[] = { { "max-cpu-usage", 1, nullptr, IConfig::CPUMaxThreadsKey }, { "cpu-max-threads-hint", 1, nullptr, IConfig::CPUMaxThreadsKey }, { "cpu-memory-pool", 1, nullptr, IConfig::MemoryPoolKey }, + { "cpu-no-yield", 0, nullptr, IConfig::YieldKey }, # ifdef XMRIG_FEATURE_TLS { "tls", 0, nullptr, IConfig::TlsKey }, { "tls-fingerprint", 1, nullptr, IConfig::FingerprintKey }, diff --git a/src/core/config/usage.h b/src/core/config/usage.h index dcae30f4a..38a487010 100644 --- a/src/core/config/usage.h +++ b/src/core/config/usage.h @@ -80,6 +80,7 @@ static inline const std::string &usage() u += " --cpu-priority set process priority (0 idle, 2 normal to 5 highest)\n"; u += " --cpu-max-threads-hint=N maximum CPU threads count (in percentage) hint for autoconfig\n"; 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"; u += " --asm=ASM ASM optimizations, possible values: auto, none, intel, ryzen, bulldozer\n"; diff --git a/src/crypto/common/VirtualMemory_hwloc.cpp b/src/crypto/common/VirtualMemory_hwloc.cpp index 6ccc0c23e..e9e23aa9d 100644 --- a/src/crypto/common/VirtualMemory_hwloc.cpp +++ b/src/crypto/common/VirtualMemory_hwloc.cpp @@ -43,9 +43,6 @@ uint32_t xmrig::VirtualMemory::bindToNUMANode(int64_t affinity) auto cpu = static_cast(Cpu::info()); hwloc_obj_t pu = hwloc_get_pu_obj_by_os_index(cpu->topology(), static_cast(affinity)); - char *buffer; - hwloc_bitmap_asprintf(&buffer, pu->cpuset); - if (pu == nullptr || !cpu->membind(pu->nodeset)) { LOG_WARN("CPU #%02" PRId64 " warning: \"can't bind memory\"", affinity); diff --git a/src/version.h b/src/version.h index 1cbae1b0f..6e21c416e 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 "5.1.0" +#define APP_VERSION "5.1.1-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2019 xmrig.com" @@ -36,7 +36,7 @@ #define APP_VER_MAJOR 5 #define APP_VER_MINOR 1 -#define APP_VER_PATCH 0 +#define APP_VER_PATCH 1 #ifdef _MSC_VER # if (_MSC_VER >= 1920)