From 42dc914eecb8c4b17efda3a6203bb06d723bf767 Mon Sep 17 00:00:00 2001 From: XMRig Date: Wed, 7 Aug 2019 18:12:39 +0700 Subject: [PATCH] Added alternative object format for CPU threads. --- doc/CPU.md | 6 ++ src/backend/common/Threads.cpp | 2 +- src/backend/cpu/CpuThreads.cpp | 90 +++++++++++++++++++++++++++-- src/backend/cpu/CpuThreads.h | 7 +++ src/core/config/ConfigTransform.cpp | 47 ++------------- 5 files changed, 106 insertions(+), 46 deletions(-) diff --git a/doc/CPU.md b/doc/CPU.md index f5d07745..15c3bf79 100644 --- a/doc/CPU.md +++ b/doc/CPU.md @@ -9,6 +9,7 @@ Example below demonstrate all primary ideas of flexible profiles configuration: * `"rx/wow"` Exact match to algorithm `rx/wow`, defined 4 threads without CPU affinity. * `"cn"` Default failback profile for all `cn/*` algorithms, defined 2 threads with CPU affinity, another failback profiles is `cn-lite`, `cn-heavy` and `rx`. * `"cn-lite"` Default failback profile for all `cn-lite/*` algorithms, defined 2 double threads with CPU affinity. +* `"cn-pico"` Alternative short object format, since 2.99.5. * `"custom-profile"` Custom user defined profile. * `"*"` Failback profile for all unhandled by other profiles algorithms. * `"cn/r"` Exact match, alias to profile `custom-profile`. @@ -34,6 +35,11 @@ Example below demonstrate all primary ideas of flexible profiles configuration: "affinity": 2 } ], + "cn-pico": { + "intensity": 2, + "threads": 8, + "affinity": -1 + }, "custom-profile": [0, 2], "*": [-1], "cn/r": "custom-profile", diff --git a/src/backend/common/Threads.cpp b/src/backend/common/Threads.cpp index 323352d1..17fc2951 100644 --- a/src/backend/common/Threads.cpp +++ b/src/backend/common/Threads.cpp @@ -55,7 +55,7 @@ size_t xmrig::Threads::read(const rapidjson::Value &value) using namespace rapidjson; for (auto &member : value.GetObject()) { - if (member.value.IsArray()) { + if (member.value.IsArray() || member.value.IsObject()) { T threads(member.value); if (!threads.isEmpty()) { diff --git a/src/backend/cpu/CpuThreads.cpp b/src/backend/cpu/CpuThreads.cpp index f877c9d3..2e8b9e1f 100644 --- a/src/backend/cpu/CpuThreads.cpp +++ b/src/backend/cpu/CpuThreads.cpp @@ -23,10 +23,66 @@ */ +#include + + #include "backend/cpu/CpuThreads.h" +#include "base/io/json/Json.h" #include "rapidjson/document.h" +namespace xmrig { + + +static const char *kAffinity = "affinity"; +static const char *kIntensity = "intensity"; +static const char *kThreads = "threads"; + + +static inline int64_t getAffinityMask(const rapidjson::Value &value) +{ + if (value.IsInt64()) { + return value.GetInt64(); + } + + if (value.IsString()) { + const char *arg = value.GetString(); + const char *p = strstr(arg, "0x"); + + return p ? strtoll(p, nullptr, 16) : strtoll(arg, nullptr, 10); + } + + return -1L; +} + + +static inline int64_t getAffinity(uint64_t index, int64_t affinity) +{ + if (affinity == -1L) { + return -1L; + } + + size_t idx = 0; + + for (size_t i = 0; i < 64; i++) { + if (!(static_cast(affinity) & (1ULL << i))) { + continue; + } + + if (idx == index) { + return static_cast(i); + } + + idx++; + } + + return -1L; +} + + +} + + xmrig::CpuThreads::CpuThreads(const rapidjson::Value &value) { if (value.IsArray()) { @@ -37,6 +93,20 @@ xmrig::CpuThreads::CpuThreads(const rapidjson::Value &value) } } } + else if (value.IsObject()) { + int intensity = Json::getInt(value, kIntensity, 1); + const size_t threads = std::min(Json::getUint(value, kThreads), 1024); + m_affinity = getAffinityMask(Json::getValue(value, kAffinity)); + m_format = ObjectFormat; + + if (intensity < 1 || intensity > 5) { + intensity = 1; + } + + for (size_t i = 0; i < threads; ++i) { + add(getAffinity(i, m_affinity), intensity); + } + } } @@ -45,10 +115,22 @@ rapidjson::Value xmrig::CpuThreads::toJSON(rapidjson::Document &doc) const using namespace rapidjson; auto &allocator = doc.GetAllocator(); - Value array(kArrayType); - for (const CpuThread &thread : m_data) { - array.PushBack(thread.toJSON(doc), allocator); + Value out; + + if (m_format == ArrayFormat) { + out.SetArray(); + + for (const CpuThread &thread : m_data) { + out.PushBack(thread.toJSON(doc), allocator); + } + } + else { + out.SetObject(); + + out.AddMember(StringRef(kIntensity), m_data.empty() ? 1 : m_data.front().intensity(), allocator); + out.AddMember(StringRef(kThreads), static_cast(m_data.size()), allocator); + out.AddMember(StringRef(kAffinity), m_affinity, allocator); } - return array; + return out; } diff --git a/src/backend/cpu/CpuThreads.h b/src/backend/cpu/CpuThreads.h index 3951c202..9d03e78b 100644 --- a/src/backend/cpu/CpuThreads.h +++ b/src/backend/cpu/CpuThreads.h @@ -53,6 +53,13 @@ public: rapidjson::Value toJSON(rapidjson::Document &doc) const; private: + enum Format { + ArrayFormat, + ObjectFormat + }; + + Format m_format = ArrayFormat; + int64_t m_affinity = -1; std::vector m_data; }; diff --git a/src/core/config/ConfigTransform.cpp b/src/core/config/ConfigTransform.cpp index ed315fb4..622855af 100644 --- a/src/core/config/ConfigTransform.cpp +++ b/src/core/config/ConfigTransform.cpp @@ -36,6 +36,7 @@ static const char *kAffinity = "affinity"; static const char *kAsterisk = "*"; static const char *kCpu = "cpu"; static const char *kIntensity = "intensity"; +static const char *kThreads = "threads"; #ifdef XMRIG_ALGO_RANDOMX static const char *kRandomX = "randomx"; @@ -79,30 +80,6 @@ static inline bool isHwAes(uint64_t av) } -static inline int64_t affinity(uint64_t index, int64_t affinity) -{ - if (affinity == -1L) { - return -1L; - } - - size_t idx = 0; - - for (size_t i = 0; i < 64; i++) { - if (!(static_cast(affinity) & (1ULL << i))) { - continue; - } - - if (idx == index) { - return static_cast(i); - } - - idx++; - } - - return -1L; -} - - } @@ -123,24 +100,12 @@ void xmrig::ConfigTransform::finalize(rapidjson::Document &doc) doc.AddMember(StringRef(kCpu), Value(kObjectType), allocator); } - Value threads(kArrayType); + Value profile(kObjectType); + profile.AddMember(StringRef(kIntensity), m_intensity, allocator); + profile.AddMember(StringRef(kThreads), m_threads, allocator); + profile.AddMember(StringRef(kAffinity), m_affinity, allocator); - if (m_intensity > 1) { - for (uint64_t i = 0; i < m_threads; ++i) { - Value thread(kObjectType); - thread.AddMember(StringRef(kIntensity), m_intensity, allocator); - thread.AddMember(StringRef(kAffinity), affinity(i, m_affinity), allocator); - - threads.PushBack(thread, doc.GetAllocator()); - } - } - else { - for (uint64_t i = 0; i < m_threads; ++i) { - threads.PushBack(affinity(i, m_affinity), doc.GetAllocator()); - } - } - - doc[kCpu].AddMember(StringRef(kAsterisk), threads, doc.GetAllocator()); + doc[kCpu].AddMember(StringRef(kAsterisk), profile, doc.GetAllocator()); } }