mirror of
https://github.com/xmrig/xmrig.git
synced 2025-01-10 21:04:37 +00:00
Merge branch 'dev'
This commit is contained in:
commit
fb721edc20
14 changed files with 138 additions and 82 deletions
|
@ -1,3 +1,6 @@
|
|||
# v6.6.1
|
||||
- Fixed, benchmark validation on NUMA hardware produced incorrect results in some conditions.
|
||||
|
||||
# v6.6.0
|
||||
- Online benchmark protocol upgraded to v2, validation not compatible with previous versions.
|
||||
- Single thread benchmark now is cheat-resistant, not possible speedup it with multiple threads.
|
||||
|
|
|
@ -33,17 +33,26 @@
|
|||
namespace xmrig {
|
||||
|
||||
|
||||
static bool done = false;
|
||||
static std::mutex mutex;
|
||||
static std::shared_ptr<Async> async;
|
||||
static uint32_t remaining = 0;
|
||||
static uint64_t doneTime = 0;
|
||||
static uint64_t result = 0;
|
||||
static uint64_t topDiff = 0;
|
||||
class BenchStatePrivate
|
||||
{
|
||||
public:
|
||||
BenchStatePrivate(IBenchListener *listener, uint32_t size) :
|
||||
listener(listener),
|
||||
size(size)
|
||||
{}
|
||||
|
||||
|
||||
IBenchListener *BenchState::m_listener = nullptr;
|
||||
uint32_t BenchState::m_size = 0;
|
||||
IBenchListener *listener;
|
||||
std::mutex mutex;
|
||||
std::shared_ptr<Async> async;
|
||||
uint32_t remaining = 0;
|
||||
uint32_t size;
|
||||
uint64_t doneTime = 0;
|
||||
};
|
||||
|
||||
|
||||
static BenchStatePrivate *d_ptr = nullptr;
|
||||
std::atomic<uint64_t> BenchState::m_data{};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
@ -52,7 +61,13 @@ uint32_t BenchState::m_size = 0;
|
|||
|
||||
bool xmrig::BenchState::isDone()
|
||||
{
|
||||
return xmrig::done;
|
||||
return d_ptr == nullptr;
|
||||
}
|
||||
|
||||
|
||||
uint32_t xmrig::BenchState::size()
|
||||
{
|
||||
return d_ptr ? d_ptr->size : 0U;
|
||||
}
|
||||
|
||||
|
||||
|
@ -71,18 +86,18 @@ uint64_t xmrig::BenchState::referenceHash(const Algorithm &algo, uint32_t size,
|
|||
|
||||
uint64_t xmrig::BenchState::start(size_t threads, const IBackend *backend)
|
||||
{
|
||||
assert(m_listener != nullptr);
|
||||
assert(d_ptr != nullptr);
|
||||
|
||||
remaining = static_cast<uint32_t>(threads);
|
||||
d_ptr->remaining = static_cast<uint32_t>(threads);
|
||||
|
||||
async = std::make_shared<Async>([] {
|
||||
m_listener->onBenchDone(result, topDiff, doneTime);
|
||||
async.reset();
|
||||
xmrig::done = true;
|
||||
d_ptr->async = std::make_shared<Async>([] {
|
||||
d_ptr->listener->onBenchDone(m_data, 0, d_ptr->doneTime);
|
||||
|
||||
destroy();
|
||||
});
|
||||
|
||||
const uint64_t ts = Chrono::steadyMSecs();
|
||||
m_listener->onBenchReady(ts, remaining, backend);
|
||||
d_ptr->listener->onBenchReady(ts, d_ptr->remaining, backend);
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
@ -90,23 +105,39 @@ uint64_t xmrig::BenchState::start(size_t threads, const IBackend *backend)
|
|||
|
||||
void xmrig::BenchState::destroy()
|
||||
{
|
||||
xmrig::done = true;
|
||||
async.reset();
|
||||
delete d_ptr;
|
||||
d_ptr = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::BenchState::done(uint64_t data, uint64_t diff, uint64_t ts)
|
||||
void xmrig::BenchState::done()
|
||||
{
|
||||
assert(async && remaining > 0);
|
||||
assert(d_ptr != nullptr && d_ptr->async && d_ptr->remaining > 0);
|
||||
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
const uint64_t ts = Chrono::steadyMSecs();
|
||||
|
||||
result ^= data;
|
||||
doneTime = std::max(doneTime, ts);
|
||||
topDiff = std::max(topDiff, diff);
|
||||
--remaining;
|
||||
std::lock_guard<std::mutex> lock(d_ptr->mutex);
|
||||
|
||||
if (remaining == 0) {
|
||||
async->send();
|
||||
d_ptr->doneTime = std::max(d_ptr->doneTime, ts);
|
||||
--d_ptr->remaining;
|
||||
|
||||
if (d_ptr->remaining == 0) {
|
||||
d_ptr->async->send();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::BenchState::init(IBenchListener *listener, uint32_t size)
|
||||
{
|
||||
assert(d_ptr == nullptr);
|
||||
|
||||
d_ptr = new BenchStatePrivate(listener, size);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::BenchState::setSize(uint32_t size)
|
||||
{
|
||||
assert(d_ptr != nullptr);
|
||||
|
||||
d_ptr->size = size;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#define XMRIG_BENCHSTATE_H
|
||||
|
||||
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
|
@ -36,18 +37,19 @@ class BenchState
|
|||
{
|
||||
public:
|
||||
static bool isDone();
|
||||
static uint32_t size();
|
||||
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 uint32_t size() { return m_size; }
|
||||
inline static void setListener(IBenchListener *listener) { m_listener = listener; }
|
||||
inline static void setSize(uint32_t size) { m_size = 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 IBenchListener *m_listener;
|
||||
static uint32_t m_size;
|
||||
static std::atomic<uint64_t> m_data;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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<Benchmark>(threads.size(), this);
|
||||
}
|
||||
# endif
|
||||
|
|
|
@ -113,7 +113,7 @@ size_t xmrig::CpuConfig::memPoolSize() const
|
|||
}
|
||||
|
||||
|
||||
std::vector<xmrig::CpuLaunchData> xmrig::CpuConfig::get(const Miner *miner, const Algorithm &algorithm, uint32_t benchSize) const
|
||||
std::vector<xmrig::CpuLaunchData> xmrig::CpuConfig::get(const Miner *miner, const Algorithm &algorithm) const
|
||||
{
|
||||
std::vector<CpuLaunchData> out;
|
||||
const auto &threads = m_threads.get(algorithm);
|
||||
|
@ -126,7 +126,7 @@ std::vector<xmrig::CpuLaunchData> 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;
|
||||
|
|
|
@ -72,7 +72,7 @@ public:
|
|||
bool isHwAES() const;
|
||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||
size_t memPoolSize() const;
|
||||
std::vector<CpuLaunchData> get(const Miner *miner, const Algorithm &algorithm, uint32_t benchSize) const;
|
||||
std::vector<CpuLaunchData> get(const Miner *miner, const Algorithm &algorithm) const;
|
||||
void read(const rapidjson::Value &value);
|
||||
|
||||
inline bool isEnabled() const { return m_enabled; }
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include <algorithm>
|
||||
|
||||
|
||||
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<uint32_t>(thread.intensity(), algorithm.maxIntensity()))
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -62,20 +62,6 @@ namespace xmrig {
|
|||
|
||||
static constexpr uint32_t kReserveCount = 32768;
|
||||
|
||||
|
||||
template<size_t N>
|
||||
inline bool nextRound(WorkerJob<N> &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<N>::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<N>::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<N>::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<N>::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<N>::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<N>::start()
|
|||
}
|
||||
|
||||
|
||||
template<size_t N>
|
||||
bool xmrig::CpuWorker<N>::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<size_t N>
|
||||
bool xmrig::CpuWorker<N>::verify(const Algorithm &algorithm, const uint8_t *referenceValue)
|
||||
{
|
||||
|
@ -395,12 +398,17 @@ void xmrig::CpuWorker<N>::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();
|
||||
|
|
|
@ -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<N> 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
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -51,8 +51,7 @@ xmrig::BenchClient::BenchClient(const std::shared_ptr<BenchConfig> &benchmark, I
|
|||
blob[Job::kMaxSeedSize * 2] = '\0';
|
||||
m_job.setSeedHash(blob.data());
|
||||
|
||||
BenchState::setListener(this);
|
||||
BenchState::setSize(m_benchmark->size());
|
||||
BenchState::init(this, m_benchmark->size());
|
||||
|
||||
# ifdef XMRIG_FEATURE_HTTP
|
||||
if (m_benchmark->isSubmit()) {
|
||||
|
@ -75,6 +74,9 @@ xmrig::BenchClient::BenchClient(const std::shared_ptr<BenchConfig> &benchmark, I
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
m_job.setBenchSize(m_benchmark->size());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -219,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;
|
||||
|
@ -286,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();
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#define APP_ID "xmrig"
|
||||
#define APP_NAME "XMRig"
|
||||
#define APP_DESC "XMRig miner"
|
||||
#define APP_VERSION "6.6.0"
|
||||
#define APP_VERSION "6.6.1-dev"
|
||||
#define APP_DOMAIN "xmrig.com"
|
||||
#define APP_SITE "www.xmrig.com"
|
||||
#define APP_COPYRIGHT "Copyright (C) 2016-2020 xmrig.com"
|
||||
|
@ -36,7 +36,7 @@
|
|||
|
||||
#define APP_VER_MAJOR 6
|
||||
#define APP_VER_MINOR 6
|
||||
#define APP_VER_PATCH 0
|
||||
#define APP_VER_PATCH 1
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# if (_MSC_VER >= 1920)
|
||||
|
|
Loading…
Reference in a new issue