diff --git a/CHANGELOG.md b/CHANGELOG.md index b1b4cf2f..25773a77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# v6.22.2 +- [#3569](https://github.com/xmrig/xmrig/pull/3569) Fixed corrupted API output in some rare conditions. +- [#3571](https://github.com/xmrig/xmrig/pull/3571) Fixed number of threads on the new Intel Core Ultra CPUs. + # v6.22.1 - [#3531](https://github.com/xmrig/xmrig/pull/3531) Always reset nonce on RandomX dataset change. - [#3534](https://github.com/xmrig/xmrig/pull/3534) Fixed threads auto-config on Zen5. diff --git a/src/backend/common/Hashrate.cpp b/src/backend/common/Hashrate.cpp index 2d8c8ce2..a5102fd1 100644 --- a/src/backend/common/Hashrate.cpp +++ b/src/backend/common/Hashrate.cpp @@ -30,10 +30,10 @@ #include "base/tools/Handle.h" -inline static const char *format(double h, char *buf, size_t size) +inline static const char *format(std::pair h, char *buf, size_t size) { - if (std::isnormal(h)) { - snprintf(buf, size, (h < 100.0) ? "%04.2f" : "%03.1f", h); + if (h.first) { + snprintf(buf, size, (h.second < 100.0) ? "%04.2f" : "%03.1f", h.second); return buf; } @@ -80,15 +80,16 @@ double xmrig::Hashrate::average() const } -const char *xmrig::Hashrate::format(double h, char *buf, size_t size) +const char *xmrig::Hashrate::format(std::pair h, char *buf, size_t size) { return ::format(h, buf, size); } -rapidjson::Value xmrig::Hashrate::normalize(double d) +rapidjson::Value xmrig::Hashrate::normalize(std::pair d) { - return Json::normalize(d, false); + using namespace rapidjson; + return d.first ? Value(floor(d.second * 100.0) / 100.0) : Value(kNullType); } @@ -122,11 +123,11 @@ rapidjson::Value xmrig::Hashrate::toJSON(size_t threadId, rapidjson::Document &d #endif -double xmrig::Hashrate::hashrate(size_t index, size_t ms) const +std::pair xmrig::Hashrate::hashrate(size_t index, size_t ms) const { assert(index < m_threads); if (index >= m_threads) { - return nan(""); + return { false, 0.0 }; } uint64_t earliestHashCount = 0; @@ -157,17 +158,27 @@ double xmrig::Hashrate::hashrate(size_t index, size_t ms) const } while (idx != idx_start); if (!haveFullSet || earliestStamp == 0 || lastestStamp == 0) { - return nan(""); + return { false, 0.0 }; } - if (lastestStamp - earliestStamp == 0) { - return nan(""); + if (lastestHashCnt == earliestHashCount) { + return { true, 0.0 }; + } + + if (lastestStamp == earliestStamp) { + return { false, 0.0 }; } const auto hashes = static_cast(lastestHashCnt - earliestHashCount); - const auto time = static_cast(lastestStamp - earliestStamp) / 1000.0; + const auto time = static_cast(lastestStamp - earliestStamp); - return hashes / time; + const auto hr = hashes * 1000.0 / time; + + if (!std::isnormal(hr)) { + return { false, 0.0 }; + } + + return { true, hr }; } diff --git a/src/backend/common/Hashrate.h b/src/backend/common/Hashrate.h index 7d753a3d..10859741 100644 --- a/src/backend/common/Hashrate.h +++ b/src/backend/common/Hashrate.h @@ -47,16 +47,16 @@ public: Hashrate(size_t threads); ~Hashrate(); - inline double calc(size_t ms) const { const double data = hashrate(0U, ms); return std::isnormal(data) ? data : 0.0; } - inline double calc(size_t threadId, size_t ms) const { return hashrate(threadId + 1, ms); } + inline std::pair calc(size_t ms) const { return hashrate(0U, ms); } + inline std::pair calc(size_t threadId, size_t ms) const { return hashrate(threadId + 1, ms); } inline size_t threads() const { return m_threads > 0U ? m_threads - 1U : 0U; } 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); + static const char *format(std::pair h, char *buf, size_t size); + static rapidjson::Value normalize(std::pair d); # ifdef XMRIG_FEATURE_API rapidjson::Value toJSON(rapidjson::Document &doc) const; @@ -64,7 +64,7 @@ public: # endif private: - double hashrate(size_t index, size_t ms) const; + std::pair hashrate(size_t index, size_t ms) const; void addData(size_t index, uint64_t count, uint64_t timestamp); constexpr static size_t kBucketSize = 2 << 11; diff --git a/src/backend/cpu/platform/HwlocCpuInfo.cpp b/src/backend/cpu/platform/HwlocCpuInfo.cpp index eb83d02d..e96edbeb 100644 --- a/src/backend/cpu/platform/HwlocCpuInfo.cpp +++ b/src/backend/cpu/platform/HwlocCpuInfo.cpp @@ -342,7 +342,7 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith } # ifdef XMRIG_ALGO_RANDOMX - if ((algorithm.family() == Algorithm::RANDOM_X) && L3_exclusive && (PUs > cores.size()) && (PUs < cores.size() * 2)) { + if ((vendor() == VENDOR_INTEL) && (algorithm.family() == Algorithm::RANDOM_X) && L3_exclusive && (PUs < cores.size() * 2)) { // Use all L3+L2 on latest Intel CPUs with P-cores, E-cores and exclusive L3 cache cacheHashes = (L3 + L2) / scratchpad; } diff --git a/src/backend/cuda/CudaBackend.cpp b/src/backend/cuda/CudaBackend.cpp index 5a732ae1..25635cbd 100644 --- a/src/backend/cuda/CudaBackend.cpp +++ b/src/backend/cuda/CudaBackend.cpp @@ -372,15 +372,20 @@ void xmrig::CudaBackend::printHashrate(bool details) char num[16 * 3] = { 0 }; - const double hashrate_short = hashrate()->calc(Hashrate::ShortInterval); - const double hashrate_medium = hashrate()->calc(Hashrate::MediumInterval); - const double hashrate_large = hashrate()->calc(Hashrate::LargeInterval); + auto hashrate_short = hashrate()->calc(Hashrate::ShortInterval); + auto hashrate_medium = hashrate()->calc(Hashrate::MediumInterval); + auto hashrate_large = hashrate()->calc(Hashrate::LargeInterval); double scale = 1.0; const char* h = " H/s"; - if ((hashrate_short >= 1e6) || (hashrate_medium >= 1e6) || (hashrate_large >= 1e6)) { + if ((hashrate_short.second >= 1e6) || (hashrate_medium.second >= 1e6) || (hashrate_large.second >= 1e6)) { scale = 1e-6; + + hashrate_short.second *= scale; + hashrate_medium.second *= scale; + hashrate_large.second *= scale; + h = "MH/s"; } @@ -388,12 +393,20 @@ void xmrig::CudaBackend::printHashrate(bool details) size_t i = 0; for (const auto& data : d_ptr->threads) { - Log::print("| %8zu | %8" PRId64 " | %8s | %8s | %8s |" CYAN_BOLD(" #%u") YELLOW(" %s") GREEN(" %s"), + auto h0 = hashrate()->calc(i, Hashrate::ShortInterval); + auto h1 = hashrate()->calc(i, Hashrate::MediumInterval); + auto h2 = hashrate()->calc(i, Hashrate::LargeInterval); + + h0.second *= scale; + h1.second *= scale; + h2.second *= scale; + + Log::print("| %8zu | %8" PRId64 " | %8s | %8s | %8s |" CYAN_BOLD(" #%u") YELLOW(" %s") GREEN(" %s"), i, data.thread.affinity(), - Hashrate::format(hashrate()->calc(i, Hashrate::ShortInterval) * scale, num, sizeof num / 3), - Hashrate::format(hashrate()->calc(i, Hashrate::MediumInterval) * scale, num + 16, sizeof num / 3), - Hashrate::format(hashrate()->calc(i, Hashrate::LargeInterval) * scale, num + 16 * 2, sizeof num / 3), + Hashrate::format(h0, num, sizeof num / 3), + Hashrate::format(h1, num + 16, sizeof num / 3), + Hashrate::format(h2, num + 16 * 2, sizeof num / 3), data.device.index(), data.device.topology().toString().data(), data.device.name().data() @@ -403,9 +416,9 @@ void xmrig::CudaBackend::printHashrate(bool details) } Log::print(WHITE_BOLD_S "| - | - | %8s | %8s | %8s |", - Hashrate::format(hashrate_short * scale, num, sizeof num / 3), - Hashrate::format(hashrate_medium * scale, num + 16, sizeof num / 3), - Hashrate::format(hashrate_large * scale, num + 16 * 2, sizeof num / 3) + Hashrate::format(hashrate_short , num, sizeof num / 3), + Hashrate::format(hashrate_medium, num + 16, sizeof num / 3), + Hashrate::format(hashrate_large , num + 16 * 2, sizeof num / 3) ); } diff --git a/src/backend/opencl/OclBackend.cpp b/src/backend/opencl/OclBackend.cpp index 493ad4c8..820c63d4 100644 --- a/src/backend/opencl/OclBackend.cpp +++ b/src/backend/opencl/OclBackend.cpp @@ -352,15 +352,20 @@ void xmrig::OclBackend::printHashrate(bool details) char num[16 * 3] = { 0 }; - const double hashrate_short = hashrate()->calc(Hashrate::ShortInterval); - const double hashrate_medium = hashrate()->calc(Hashrate::MediumInterval); - const double hashrate_large = hashrate()->calc(Hashrate::LargeInterval); + auto hashrate_short = hashrate()->calc(Hashrate::ShortInterval); + auto hashrate_medium = hashrate()->calc(Hashrate::MediumInterval); + auto hashrate_large = hashrate()->calc(Hashrate::LargeInterval); double scale = 1.0; const char* h = " H/s"; - if ((hashrate_short >= 1e6) || (hashrate_medium >= 1e6) || (hashrate_large >= 1e6)) { + if ((hashrate_short.second >= 1e6) || (hashrate_medium.second >= 1e6) || (hashrate_large.second >= 1e6)) { scale = 1e-6; + + hashrate_short.second *= scale; + hashrate_medium.second *= scale; + hashrate_large.second *= scale; + h = "MH/s"; } @@ -368,12 +373,16 @@ void xmrig::OclBackend::printHashrate(bool details) size_t i = 0; for (const auto& data : d_ptr->threads) { - Log::print("| %8zu | %8" PRId64 " | %8s | %8s | %8s |" CYAN_BOLD(" #%u") YELLOW(" %s") " %s", + auto h0 = hashrate()->calc(i, Hashrate::ShortInterval); + auto h1 = hashrate()->calc(i, Hashrate::MediumInterval); + auto h2 = hashrate()->calc(i, Hashrate::LargeInterval); + + Log::print("| %8zu | %8" PRId64 " | %8s | %8s | %8s |" CYAN_BOLD(" #%u") YELLOW(" %s") " %s", i, data.affinity, - Hashrate::format(hashrate()->calc(i, Hashrate::ShortInterval) * scale, num, sizeof num / 3), - Hashrate::format(hashrate()->calc(i, Hashrate::MediumInterval) * scale, num + 16, sizeof num / 3), - Hashrate::format(hashrate()->calc(i, Hashrate::LargeInterval) * scale, num + 16 * 2, sizeof num / 3), + Hashrate::format(h0, num, sizeof num / 3), + Hashrate::format(h1, num + 16, sizeof num / 3), + Hashrate::format(h2, num + 16 * 2, sizeof num / 3), data.device.index(), data.device.topology().toString().data(), data.device.printableName().data() @@ -383,9 +392,9 @@ void xmrig::OclBackend::printHashrate(bool details) } Log::print(WHITE_BOLD_S "| - | - | %8s | %8s | %8s |", - Hashrate::format(hashrate_short * scale, num, sizeof num / 3), - Hashrate::format(hashrate_medium * scale, num + 16, sizeof num / 3), - Hashrate::format(hashrate_large * scale, num + 16 * 2, sizeof num / 3) + Hashrate::format(hashrate_short , num, sizeof num / 3), + Hashrate::format(hashrate_medium, num + 16, sizeof num / 3), + Hashrate::format(hashrate_large , num + 16 * 2, sizeof num / 3) ); } diff --git a/src/core/Miner.cpp b/src/core/Miner.cpp index e2b1d596..1f99b943 100644 --- a/src/core/Miner.cpp +++ b/src/core/Miner.cpp @@ -173,7 +173,7 @@ public: Value total(kArrayType); Value threads(kArrayType); - double t[3] = { 0.0 }; + std::pair t[3] = { { true, 0.0 }, { true, 0.0 }, { true, 0.0 } }; for (IBackend *backend : backends) { const Hashrate *hr = backend->hashrate(); @@ -181,9 +181,13 @@ public: continue; } - t[0] += hr->calc(Hashrate::ShortInterval); - t[1] += hr->calc(Hashrate::MediumInterval); - t[2] += hr->calc(Hashrate::LargeInterval); + const auto h0 = hr->calc(Hashrate::ShortInterval); + const auto h1 = hr->calc(Hashrate::MediumInterval); + const auto h2 = hr->calc(Hashrate::LargeInterval); + + if (h0.first) { t[0].second += h0.second; } else { t[0].first = false; } + if (h1.first) { t[1].second += h1.second; } else { t[1].first = false; } + if (h2.first) { t[2].second += h2.second; } else { t[2].first = false; } if (version > 1) { continue; @@ -204,7 +208,7 @@ public: total.PushBack(Hashrate::normalize(t[2]), allocator); hashrate.AddMember("total", total, allocator); - hashrate.AddMember("highest", Hashrate::normalize(maxHashrate[algorithm]), allocator); + hashrate.AddMember("highest", Hashrate::normalize({ maxHashrate[algorithm] > 0.0, maxHashrate[algorithm] }), allocator); if (version == 1) { hashrate.AddMember("threads", threads, allocator); @@ -283,7 +287,7 @@ public: void printHashrate(bool details) { char num[16 * 5] = { 0 }; - double speed[3] = { 0.0 }; + std::pair speed[3] = { { true, 0.0 }, { true, 0.0 }, { true, 0.0 } }; uint32_t count = 0; double avg_hashrate = 0.0; @@ -293,9 +297,13 @@ public: if (hashrate) { ++count; - speed[0] += hashrate->calc(Hashrate::ShortInterval); - speed[1] += hashrate->calc(Hashrate::MediumInterval); - speed[2] += hashrate->calc(Hashrate::LargeInterval); + const auto h0 = hashrate->calc(Hashrate::ShortInterval); + const auto h1 = hashrate->calc(Hashrate::MediumInterval); + const auto h2 = hashrate->calc(Hashrate::LargeInterval); + + if (h0.first) { speed[0].second += h0.second; } else { speed[0].first = false; } + if (h1.first) { speed[1].second += h1.second; } else { speed[1].first = false; } + if (h2.first) { speed[2].second += h2.second; } else { speed[2].first = false; } avg_hashrate += hashrate->average(); } @@ -312,8 +320,13 @@ public: double scale = 1.0; const char* h = "H/s"; - if ((speed[0] >= 1e6) || (speed[1] >= 1e6) || (speed[2] >= 1e6) || (maxHashrate[algorithm] >= 1e6)) { + if ((speed[0].second >= 1e6) || (speed[1].second >= 1e6) || (speed[2].second >= 1e6) || (maxHashrate[algorithm] >= 1e6)) { scale = 1e-6; + + speed[0].second *= scale; + speed[1].second *= scale; + speed[2].second *= scale; + h = "MH/s"; } @@ -322,16 +335,16 @@ public: # 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); + snprintf(avg_hashrate_buf, sizeof(avg_hashrate_buf), " avg " CYAN_BOLD("%s %s"), Hashrate::format({ true, 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, 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, + Hashrate::format(speed[0], num, 16), + Hashrate::format(speed[1], num + 16, 16), + Hashrate::format(speed[2], num + 16 * 2, 16), h, + Hashrate::format({ maxHashrate[algorithm] > 0.0, maxHashrate[algorithm] * scale }, num + 16 * 3, 16), h, avg_hashrate_buf ); @@ -646,7 +659,10 @@ void xmrig::Miner::onTimer(const Timer *) } if (backend->hashrate()) { - maxHashrate += backend->hashrate()->calc(Hashrate::ShortInterval); + const auto h = backend->hashrate()->calc(Hashrate::ShortInterval); + if (h.first) { + maxHashrate += h.second; + } } } diff --git a/src/version.h b/src/version.h index a7cd6bc0..60a1c33e 100644 --- a/src/version.h +++ b/src/version.h @@ -22,7 +22,7 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "6.22.1" +#define APP_VERSION "6.22.2-dev" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2024 xmrig.com" @@ -30,7 +30,7 @@ #define APP_VER_MAJOR 6 #define APP_VER_MINOR 22 -#define APP_VER_PATCH 1 +#define APP_VER_PATCH 2 #ifdef _MSC_VER # if (_MSC_VER >= 1930)