diff --git a/src/backend/common/benchmark/BenchState.cpp b/src/backend/common/benchmark/BenchState.cpp index 65fc1c42..ec2074dc 100644 --- a/src/backend/common/benchmark/BenchState.cpp +++ b/src/backend/common/benchmark/BenchState.cpp @@ -48,12 +48,11 @@ public: uint32_t remaining = 0; uint32_t size; uint64_t doneTime = 0; - uint64_t result = 0; - uint64_t topDiff = 0; }; static BenchStatePrivate *d_ptr = nullptr; +std::atomic BenchState::m_data{}; } // namespace xmrig @@ -92,7 +91,7 @@ uint64_t xmrig::BenchState::start(size_t threads, const IBackend *backend) d_ptr->remaining = static_cast(threads); d_ptr->async = std::make_shared([] { - d_ptr->listener->onBenchDone(d_ptr->result, d_ptr->topDiff, d_ptr->doneTime); + d_ptr->listener->onBenchDone(m_data, 0, d_ptr->doneTime); destroy(); }); @@ -111,15 +110,15 @@ void xmrig::BenchState::destroy() } -void xmrig::BenchState::done(uint64_t data, uint64_t diff, uint64_t ts) +void xmrig::BenchState::done() { assert(d_ptr != nullptr && d_ptr->async && d_ptr->remaining > 0); + const uint64_t ts = Chrono::steadyMSecs(); + std::lock_guard lock(d_ptr->mutex); - d_ptr->result ^= data; d_ptr->doneTime = std::max(d_ptr->doneTime, ts); - d_ptr->topDiff = std::max(d_ptr->topDiff, diff); --d_ptr->remaining; if (d_ptr->remaining == 0) { diff --git a/src/backend/common/benchmark/BenchState.h b/src/backend/common/benchmark/BenchState.h index ed7b3371..4dd6647f 100644 --- a/src/backend/common/benchmark/BenchState.h +++ b/src/backend/common/benchmark/BenchState.h @@ -20,6 +20,7 @@ #define XMRIG_BENCHSTATE_H +#include #include #include @@ -40,9 +41,15 @@ public: static uint64_t referenceHash(const Algorithm &algo, uint32_t size, uint32_t threads); static uint64_t start(size_t threads, const IBackend *backend); static void destroy(); - static void done(uint64_t data, uint64_t diff, uint64_t ts); + static void done(); static void init(IBenchListener *listener, uint32_t size); static void setSize(uint32_t size); + + inline static uint64_t data() { return m_data; } + inline static void add(uint64_t value) { m_data.fetch_xor(value, std::memory_order_relaxed); } + +private: + static std::atomic m_data; }; diff --git a/src/backend/cpu/CpuBackend.cpp b/src/backend/cpu/CpuBackend.cpp index a00b2653..fc6b7e74 100644 --- a/src/backend/cpu/CpuBackend.cpp +++ b/src/backend/cpu/CpuBackend.cpp @@ -347,13 +347,7 @@ void xmrig::CpuBackend::setJob(const Job &job) const auto &cpu = d_ptr->controller->config()->cpu(); -# ifdef XMRIG_FEATURE_BENCHMARK - const uint32_t benchSize = BenchState::size(); -# else - constexpr uint32_t benchSize = 0; -# endif - - auto threads = cpu.get(d_ptr->controller->miner(), job.algorithm(), benchSize); + auto threads = cpu.get(d_ptr->controller->miner(), job.algorithm()); if (!d_ptr->threads.empty() && d_ptr->threads.size() == threads.size() && std::equal(d_ptr->threads.begin(), d_ptr->threads.end(), threads.begin())) { return; } @@ -370,7 +364,7 @@ void xmrig::CpuBackend::setJob(const Job &job) stop(); # ifdef XMRIG_FEATURE_BENCHMARK - if (benchSize) { + if (BenchState::size()) { d_ptr->benchmark = std::make_shared(threads.size(), this); } # endif diff --git a/src/backend/cpu/CpuConfig.cpp b/src/backend/cpu/CpuConfig.cpp index 5614ef61..9833a5da 100644 --- a/src/backend/cpu/CpuConfig.cpp +++ b/src/backend/cpu/CpuConfig.cpp @@ -113,7 +113,7 @@ size_t xmrig::CpuConfig::memPoolSize() const } -std::vector xmrig::CpuConfig::get(const Miner *miner, const Algorithm &algorithm, uint32_t benchSize) const +std::vector xmrig::CpuConfig::get(const Miner *miner, const Algorithm &algorithm) const { std::vector out; const auto &threads = m_threads.get(algorithm); @@ -126,7 +126,7 @@ std::vector xmrig::CpuConfig::get(const Miner *miner, cons out.reserve(count); for (const auto &thread : threads.data()) { - out.emplace_back(miner, algorithm, *this, thread, benchSize, count); + out.emplace_back(miner, algorithm, *this, thread, count); } return out; diff --git a/src/backend/cpu/CpuConfig.h b/src/backend/cpu/CpuConfig.h index 4add6553..95defa67 100644 --- a/src/backend/cpu/CpuConfig.h +++ b/src/backend/cpu/CpuConfig.h @@ -72,7 +72,7 @@ public: bool isHwAES() const; rapidjson::Value toJSON(rapidjson::Document &doc) const; size_t memPoolSize() const; - std::vector get(const Miner *miner, const Algorithm &algorithm, uint32_t benchSize) const; + std::vector get(const Miner *miner, const Algorithm &algorithm) const; void read(const rapidjson::Value &value); inline bool isEnabled() const { return m_enabled; } diff --git a/src/backend/cpu/CpuLaunchData.cpp b/src/backend/cpu/CpuLaunchData.cpp index 94628c84..a5e0c99e 100644 --- a/src/backend/cpu/CpuLaunchData.cpp +++ b/src/backend/cpu/CpuLaunchData.cpp @@ -32,7 +32,7 @@ #include -xmrig::CpuLaunchData::CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread, uint32_t benchSize, size_t threads) : +xmrig::CpuLaunchData::CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread, size_t threads) : algorithm(algorithm), assembly(config.assembly()), astrobwtAVX2(config.astrobwtAVX2()), @@ -44,7 +44,6 @@ xmrig::CpuLaunchData::CpuLaunchData(const Miner *miner, const Algorithm &algorit affinity(thread.affinity()), miner(miner), threads(threads), - benchSize(benchSize), intensity(std::min(thread.intensity(), algorithm.maxIntensity())) { } diff --git a/src/backend/cpu/CpuLaunchData.h b/src/backend/cpu/CpuLaunchData.h index 8ba3180f..8801c005 100644 --- a/src/backend/cpu/CpuLaunchData.h +++ b/src/backend/cpu/CpuLaunchData.h @@ -44,7 +44,7 @@ class Miner; class CpuLaunchData { public: - CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread, uint32_t benchSize, size_t threads); + CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread, size_t threads); bool isEqual(const CpuLaunchData &other) const; CnHash::AlgoVariant av() const; @@ -67,7 +67,6 @@ public: const int64_t affinity; const Miner *miner; const size_t threads; - const uint32_t benchSize; const uint32_t intensity; }; diff --git a/src/backend/cpu/CpuWorker.cpp b/src/backend/cpu/CpuWorker.cpp index d61e8038..778f8e46 100644 --- a/src/backend/cpu/CpuWorker.cpp +++ b/src/backend/cpu/CpuWorker.cpp @@ -62,20 +62,6 @@ namespace xmrig { static constexpr uint32_t kReserveCount = 32768; - -template -inline bool nextRound(WorkerJob &job, uint32_t benchSize) -{ - if (!job.nextRound(benchSize ? 1 : kReserveCount, 1)) { - JobResults::done(job.currentJob()); - - return false; - } - - return true; -} - - } // namespace xmrig @@ -92,7 +78,6 @@ xmrig::CpuWorker::CpuWorker(size_t id, const CpuLaunchData &data) : m_astrobwtMaxSize(data.astrobwtMaxSize * 1000), m_miner(data.miner), m_threads(data.threads), - m_benchSize(data.benchSize), m_ctx() { m_memory = new VirtualMemory(m_algorithm.l3() * N, data.hugePages, false, true, m_node); @@ -241,12 +226,12 @@ void xmrig::CpuWorker::start() # ifdef XMRIG_FEATURE_BENCHMARK if (m_benchSize) { if (current_job_nonces[0] >= m_benchSize) { - return BenchState::done(m_benchData, m_benchDiff, Chrono::steadyMSecs());; + return BenchState::done(); } // Make each hash dependent on the previous one in single thread benchmark to prevent cheating with multiple threads if (m_threads == 1) { - *(uint64_t*)(m_job.blob()) ^= m_benchData; + *(uint64_t*)(m_job.blob()) ^= BenchState::data(); } } # endif @@ -260,7 +245,7 @@ void xmrig::CpuWorker::start() randomx_calculate_hash_first(m_vm, tempHash, m_job.blob(), job.size()); } - if (!nextRound(m_job, m_benchSize)) { + if (!nextRound()) { break; } @@ -280,7 +265,7 @@ void xmrig::CpuWorker::start() fn(job.algorithm())(m_job.blob(), job.size(), m_hash, m_ctx, job.height()); } - if (!nextRound(m_job, m_benchSize)) { + if (!nextRound()) { break; }; } @@ -292,8 +277,7 @@ void xmrig::CpuWorker::start() # ifdef XMRIG_FEATURE_BENCHMARK if (m_benchSize) { if (current_job_nonces[i] < m_benchSize) { - m_benchData ^= value; - m_benchDiff = std::max(m_benchDiff, Job::toDiff(value)); + BenchState::add(value); } } else @@ -315,6 +299,25 @@ void xmrig::CpuWorker::start() } +template +bool xmrig::CpuWorker::nextRound() +{ +# ifdef XMRIG_FEATURE_BENCHMARK + const uint32_t count = m_benchSize ? 1U : kReserveCount; +# else + constexpr uint32_t count = kReserveCount; +# endif + + if (!m_job.nextRound(count, 1)) { + JobResults::done(m_job.currentJob()); + + return false; + } + + return true; +} + + template bool xmrig::CpuWorker::verify(const Algorithm &algorithm, const uint8_t *referenceValue) { @@ -395,12 +398,17 @@ void xmrig::CpuWorker::consumeJob() return; } - m_job.add(m_miner->job(), m_benchSize ? 1 : kReserveCount, Nonce::CPU); + auto job = m_miner->job(); # ifdef XMRIG_FEATURE_BENCHMARK - m_benchData = 0; + m_benchSize = job.benchSize(); + const uint32_t count = m_benchSize ? 1U : kReserveCount; +# else + constexpr uint32_t count = kReserveCount; # endif + m_job.add(job, count, Nonce::CPU); + # ifdef XMRIG_ALGO_RANDOMX if (m_job.currentJob().algorithm().family() == Algorithm::RANDOM_X) { allocateRandomX_VM(); diff --git a/src/backend/cpu/CpuWorker.h b/src/backend/cpu/CpuWorker.h index 6669f5db..06c92fa4 100644 --- a/src/backend/cpu/CpuWorker.h +++ b/src/backend/cpu/CpuWorker.h @@ -68,6 +68,7 @@ private: void allocateRandomX_VM(); # endif + bool nextRound(); bool verify(const Algorithm &algorithm, const uint8_t *referenceValue); bool verify2(const Algorithm &algorithm, const uint8_t *referenceValue); void allocateCnCtx(); @@ -83,18 +84,16 @@ private: const int m_astrobwtMaxSize; const Miner *m_miner; const size_t m_threads; - const uint32_t m_benchSize; cryptonight_ctx *m_ctx[N]; VirtualMemory *m_memory = nullptr; WorkerJob m_job; # ifdef XMRIG_ALGO_RANDOMX - randomx_vm *m_vm = nullptr; + randomx_vm *m_vm = nullptr; # endif # ifdef XMRIG_FEATURE_BENCHMARK - uint64_t m_benchData = 0; - uint64_t m_benchDiff = 0; + uint32_t m_benchSize = 0; # endif }; diff --git a/src/base/net/stratum/Job.cpp b/src/base/net/stratum/Job.cpp index fc17b510..20345414 100644 --- a/src/base/net/stratum/Job.cpp +++ b/src/base/net/stratum/Job.cpp @@ -174,6 +174,10 @@ void xmrig::Job::copy(const Job &other) memcpy(m_rawBlob, other.m_rawBlob, sizeof(m_rawBlob)); memcpy(m_rawTarget, other.m_rawTarget, sizeof(m_rawTarget)); # endif + +# ifdef XMRIG_FEATURE_BENCHMARK + m_benchSize = other.m_benchSize; +# endif } @@ -205,4 +209,8 @@ void xmrig::Job::move(Job &&other) memcpy(m_rawBlob, other.m_rawBlob, sizeof(m_rawBlob)); memcpy(m_rawTarget, other.m_rawTarget, sizeof(m_rawTarget)); # endif + +# ifdef XMRIG_FEATURE_BENCHMARK + m_benchSize = other.m_benchSize; +# endif } diff --git a/src/base/net/stratum/Job.h b/src/base/net/stratum/Job.h index 761b5af2..5621cbc7 100644 --- a/src/base/net/stratum/Job.h +++ b/src/base/net/stratum/Job.h @@ -111,6 +111,11 @@ public: inline Job &operator=(const Job &other) { copy(other); return *this; } inline Job &operator=(Job &&other) noexcept { move(std::move(other)); return *this; } +# ifdef XMRIG_FEATURE_BENCHMARK + inline uint32_t benchSize() const { return m_benchSize; } + inline void setBenchSize(uint32_t size) { m_benchSize = size; } +# endif + private: void copy(const Job &other); void move(Job &&other); @@ -135,6 +140,10 @@ private: char m_rawTarget[24]{}; String m_rawSeedHash; # endif + +# ifdef XMRIG_FEATURE_BENCHMARK + uint32_t m_benchSize = 0; +# endif }; diff --git a/src/base/net/stratum/benchmark/BenchClient.cpp b/src/base/net/stratum/benchmark/BenchClient.cpp index f05359b0..003eeca7 100644 --- a/src/base/net/stratum/benchmark/BenchClient.cpp +++ b/src/base/net/stratum/benchmark/BenchClient.cpp @@ -74,6 +74,9 @@ xmrig::BenchClient::BenchClient(const std::shared_ptr &benchmark, I return; } + + m_job.setBenchSize(m_benchmark->size()); + } @@ -218,6 +221,8 @@ bool xmrig::BenchClient::setSeed(const char *seed) return false; } + m_job.setBenchSize(BenchState::size()); + LOG_NOTICE("%s " WHITE_BOLD("seed ") BLACK_BOLD("%s"), tag(), seed); return true; @@ -285,11 +290,11 @@ void xmrig::BenchClient::onGetReply(const rapidjson::Value &value) m_hash = strtoull(hash, nullptr, 16); } + BenchState::setSize(Json::getUint(value, BenchConfig::kSize)); + m_job.setAlgorithm(Json::getString(value, BenchConfig::kAlgo)); setSeed(Json::getString(value, BenchConfig::kSeed)); - BenchState::setSize(Json::getUint(value, BenchConfig::kSize)); - start(); }