From c6292ce9eee3bdb7413a50710205e0e8a154bbe7 Mon Sep 17 00:00:00 2001 From: SChernykh Date: Sat, 27 Nov 2021 12:18:19 +0100 Subject: [PATCH] GhostRider hotfixes - Added average hashrate display - Fixed the number of threads shown at startup - Fixed `--threads` or `-t` command line option (but `--cpu-max-threads-hint` is recommended to use) --- src/backend/common/Hashrate.cpp | 18 +++++++++++++++++ src/backend/common/Hashrate.h | 5 +++++ src/backend/common/Worker.h | 2 ++ src/backend/common/interfaces/IWorker.h | 1 + src/backend/cpu/CpuBackend.cpp | 4 +++- src/backend/cpu/CpuLaunchData.cpp | 2 +- src/backend/cpu/CpuWorker.h | 9 +++++++++ src/base/crypto/Algorithm.h | 1 + src/core/Miner.cpp | 26 +++++++++++++++++++------ src/crypto/ghostrider/README.md | 4 +++- 10 files changed, 63 insertions(+), 9 deletions(-) diff --git a/src/backend/common/Hashrate.cpp b/src/backend/common/Hashrate.cpp index 4038e34b9..2d8c8ce20 100644 --- a/src/backend/common/Hashrate.cpp +++ b/src/backend/common/Hashrate.cpp @@ -53,6 +53,9 @@ xmrig::Hashrate::Hashrate(size_t threads) : m_timestamps[i] = new uint64_t[kBucketSize](); m_top[i] = 0; } + + m_earliestTimestamp = std::numeric_limits::max(); + m_totalCount = 0; } @@ -66,6 +69,14 @@ xmrig::Hashrate::~Hashrate() delete [] m_counts; delete [] m_timestamps; delete [] m_top; + +} + + +double xmrig::Hashrate::average() const +{ + const uint64_t ts = Chrono::steadyMSecs(); + return (ts > m_earliestTimestamp) ? (m_totalCount * 1e3 / (ts - m_earliestTimestamp)) : 0.0; } @@ -167,4 +178,11 @@ void xmrig::Hashrate::addData(size_t index, uint64_t count, uint64_t timestamp) m_timestamps[index][top] = timestamp; m_top[index] = (top + 1) & kBucketMask; + + if (index == 0) { + if (m_earliestTimestamp == std::numeric_limits::max()) { + m_earliestTimestamp = timestamp; + } + m_totalCount = count; + } } diff --git a/src/backend/common/Hashrate.h b/src/backend/common/Hashrate.h index ad278cfa0..7d753a3db 100644 --- a/src/backend/common/Hashrate.h +++ b/src/backend/common/Hashrate.h @@ -53,6 +53,8 @@ public: inline void add(size_t threadId, uint64_t count, uint64_t timestamp) { addData(threadId + 1U, count, timestamp); } inline void add(uint64_t count, uint64_t timestamp) { addData(0U, count, timestamp); } + double average() const; + static const char *format(double h, char *buf, size_t size); static rapidjson::Value normalize(double d); @@ -72,6 +74,9 @@ private: uint32_t* m_top; uint64_t** m_counts; uint64_t** m_timestamps; + + uint64_t m_earliestTimestamp; + uint64_t m_totalCount; }; diff --git a/src/backend/common/Worker.h b/src/backend/common/Worker.h index f4c12ea52..6a94a22ac 100644 --- a/src/backend/common/Worker.h +++ b/src/backend/common/Worker.h @@ -31,6 +31,8 @@ class Worker : public IWorker public: Worker(size_t id, int64_t affinity, int priority); + size_t threads() const override { return 1; } + protected: inline int64_t affinity() const { return m_affinity; } inline size_t id() const override { return m_id; } diff --git a/src/backend/common/interfaces/IWorker.h b/src/backend/common/interfaces/IWorker.h index 7ed6ff008..43966bbf5 100644 --- a/src/backend/common/interfaces/IWorker.h +++ b/src/backend/common/interfaces/IWorker.h @@ -46,6 +46,7 @@ public: virtual const VirtualMemory *memory() const = 0; virtual size_t id() const = 0; virtual size_t intensity() const = 0; + virtual size_t threads() const = 0; virtual void hashrateData(uint64_t &hashCount, uint64_t &timeStamp, uint64_t &rawHashes) const = 0; virtual void jobEarlyNotification(const Job &job) = 0; virtual void start() = 0; diff --git a/src/backend/cpu/CpuBackend.cpp b/src/backend/cpu/CpuBackend.cpp index d5ada9adc..101975650 100644 --- a/src/backend/cpu/CpuBackend.cpp +++ b/src/backend/cpu/CpuBackend.cpp @@ -88,6 +88,7 @@ public: { if (ready) { m_started++; + m_totalStarted += worker->threads(); if (m_workersMemory.insert(worker->memory()).second) { m_hugePages += worker->memory()->hugePages(); @@ -112,7 +113,7 @@ public: LOG_INFO("%s" GREEN_BOLD(" READY") " threads %s%zu/%zu (%zu)" CLEAR " huge pages %s%1.0f%% %zu/%zu" CLEAR " memory " CYAN_BOLD("%zu KB") BLACK_BOLD(" (%" PRIu64 " ms)"), Tags::cpu(), m_errors == 0 ? CYAN_BOLD_S : YELLOW_BOLD_S, - m_started, m_threads, m_ways, + m_totalStarted, std::max(m_totalStarted, m_threads), m_ways, (m_hugePages.isFullyAllocated() ? GREEN_BOLD_S : (m_hugePages.allocated == 0 ? RED_BOLD_S : YELLOW_BOLD_S)), m_hugePages.percent(), m_hugePages.allocated, m_hugePages.total, @@ -127,6 +128,7 @@ private: size_t m_errors = 0; size_t m_memory = 0; size_t m_started = 0; + size_t m_totalStarted = 0; size_t m_threads = 0; size_t m_ways = 0; uint64_t m_ts = 0; diff --git a/src/backend/cpu/CpuLaunchData.cpp b/src/backend/cpu/CpuLaunchData.cpp index 648be815c..62b5e7373 100644 --- a/src/backend/cpu/CpuLaunchData.cpp +++ b/src/backend/cpu/CpuLaunchData.cpp @@ -44,7 +44,7 @@ xmrig::CpuLaunchData::CpuLaunchData(const Miner *miner, const Algorithm &algorit affinity(thread.affinity()), miner(miner), threads(threads), - intensity(std::min(thread.intensity(), algorithm.maxIntensity())), + intensity(std::max(std::min(thread.intensity(), algorithm.maxIntensity()), algorithm.minIntensity())), affinities(affinities) { } diff --git a/src/backend/cpu/CpuWorker.h b/src/backend/cpu/CpuWorker.h index c3ed18296..a15378ed9 100644 --- a/src/backend/cpu/CpuWorker.h +++ b/src/backend/cpu/CpuWorker.h @@ -52,6 +52,15 @@ public: CpuWorker(size_t id, const CpuLaunchData &data); ~CpuWorker() override; + size_t threads() const override + { +# ifdef XMRIG_ALGO_GHOSTRIDER + return m_ghHelper ? 2 : 1; +# else + return 1; +# endif + } + protected: bool selfTest() override; void hashrateData(uint64_t &hashCount, uint64_t &timeStamp, uint64_t &rawHashes) const override; diff --git a/src/base/crypto/Algorithm.h b/src/base/crypto/Algorithm.h index 38d804247..08508882f 100644 --- a/src/base/crypto/Algorithm.h +++ b/src/base/crypto/Algorithm.h @@ -189,6 +189,7 @@ public: inline Id id() const { return m_id; } inline size_t l2() const { return l2(m_id); } inline uint32_t family() const { return family(m_id); } + inline uint32_t minIntensity() const { return ((m_id == GHOSTRIDER_RTM) ? 8 : 1); }; inline uint32_t maxIntensity() const { return isCN() ? 5 : ((m_id == GHOSTRIDER_RTM) ? 8 : 1); }; inline size_t l3() const diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index afebde850..78ed1f6a5 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -287,10 +287,12 @@ public: void printHashrate(bool details) { - char num[16 * 4] = { 0 }; + char num[16 * 5] = { 0 }; double speed[3] = { 0.0 }; uint32_t count = 0; + double avg_hashrate = 0.0; + for (auto backend : backends) { const auto hashrate = backend->hashrate(); if (hashrate) { @@ -299,6 +301,8 @@ public: speed[0] += hashrate->calc(Hashrate::ShortInterval); speed[1] += hashrate->calc(Hashrate::MediumInterval); speed[2] += hashrate->calc(Hashrate::LargeInterval); + + avg_hashrate += hashrate->average(); } backend->printHashrate(details); @@ -318,12 +322,22 @@ public: h = "MH/s"; } - LOG_INFO("%s " WHITE_BOLD("speed") " 10s/60s/15m " CYAN_BOLD("%s") CYAN(" %s %s ") CYAN_BOLD("%s") " max " CYAN_BOLD("%s %s"), + char avg_hashrate_buf[64]; + avg_hashrate_buf[0] = '\0'; + +# ifdef XMRIG_ALGO_GHOSTRIDER + if (algorithm.family() == Algorithm::GHOSTRIDER) { + snprintf(avg_hashrate_buf, sizeof(avg_hashrate_buf), " avg " CYAN_BOLD("%s %s"), Hashrate::format(avg_hashrate * scale, num + 16 * 4, 16), h); + } +# endif + + LOG_INFO("%s " WHITE_BOLD("speed") " 10s/60s/15m " CYAN_BOLD("%s") CYAN(" %s %s ") CYAN_BOLD("%s") " max " CYAN_BOLD("%s %s") "%s", Tags::miner(), - Hashrate::format(speed[0] * scale, num, sizeof(num) / 4), - Hashrate::format(speed[1] * scale, num + 16, sizeof(num) / 4), - Hashrate::format(speed[2] * scale, num + 16 * 2, sizeof(num) / 4), h, - Hashrate::format(maxHashrate[algorithm] * scale, num + 16 * 3, sizeof(num) / 4), h + Hashrate::format(speed[0] * scale, num, 16), + Hashrate::format(speed[1] * scale, num + 16, 16), + Hashrate::format(speed[2] * scale, num + 16 * 2, 16), h, + Hashrate::format(maxHashrate[algorithm] * scale, num + 16 * 3, 16), h, + avg_hashrate_buf ); # ifdef XMRIG_FEATURE_BENCHMARK diff --git a/src/crypto/ghostrider/README.md b/src/crypto/ghostrider/README.md index 65e51c233..bce065c06 100644 --- a/src/crypto/ghostrider/README.md +++ b/src/crypto/ghostrider/README.md @@ -18,11 +18,13 @@ xmrig -a gr -o us.flockpool.com:5555 --tls -u WALLET_ADDRESS You can use **rtm_ghostrider_example.cmd** as a template and put pool URL and your wallet address there. The general XMRig documentation is available [here](https://xmrig.com/docs/miner). +**Using `--threads` or `-t` option is NOT recommended because it turns off advanced built-in config.** If you want to tweak the nubmer of threads used for GhostRider, it's recommended to start using config.json instead of command line. The best suitable command line option for this is `--cpu-max-threads-hint=N` where N can be between 0 and 100. + ## Performance While individual algorithm implementations are a bit unoptimized, XMRig achieves higher hashrates by employing better auto-config and more fine-grained thread scheduling: it can calculate a single batch of hashes using 2 threads for parts that don't require much cache. For example, on a typical Intel CPU (2 MB cache per core) it will use 1 thread per core for cn/fast, and 2 threads per core for other Cryptonight variants while calculating the same batch of hashes, always achieving more than 50% CPU load. -For the same reason, XMRig can sometimes use less than 100% CPU on Ryzen 3000/5000 CPUs if it finds that running 1 thread per core is faster for some Cryptonight variants on your system. Also, this is why it reports using only half the threads at startup - it's actually 2 threads per each reported thread. +For the same reason, XMRig can sometimes use less than 100% CPU on Ryzen 3000/5000 CPUs if it finds that running 1 thread per core is faster for some Cryptonight variants on your system. **Windows** (detailed results [here](https://imgur.com/a/GCjEWpl)) CPU|cpuminer-gr-avx2 (tuned), h/s|XMRig (MSVC build), h/s|Speedup