Merge xmrig v6.4.0 into master

This commit is contained in:
MoneroOcean 2020-10-18 22:04:56 +00:00
commit 2cf2fcaf8c
109 changed files with 7365 additions and 6359 deletions

View file

@ -0,0 +1,103 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "backend/common/Benchmark.h"
#include "backend/common/interfaces/IWorker.h"
#include "base/io/log/Log.h"
#include "base/io/log/Tags.h"
#include "base/tools/Chrono.h"
#include <algorithm>
namespace xmrig {
static uint64_t hashCheck[2][10] = {
{ 0x898B6E0431C28A6BULL, 0xEE9468F8B40926BCULL, 0xC2BC5D11724813C0ULL, 0x3A2C7B285B87F941ULL, 0x3B5BD2C3A16B450EULL, 0x5CD0602F20C5C7C4ULL, 0x101DE939474B6812ULL, 0x52B765A1B156C6ECULL, 0x323935102AB6B45CULL, 0xB5231262E2792B26ULL },
{ 0x0F3E5400B39EA96AULL, 0x85944CCFA2752D1FULL, 0x64AFFCAE991811BAULL, 0x3E4D0B836D3B13BAULL, 0xEB7417D621271166ULL, 0x97FFE10C0949FFA5ULL, 0x84CAC0F8879A4BA1ULL, 0xA1B79F031DA2459FULL, 0x9B65226DA873E65DULL, 0x0F9E00C5A511C200ULL },
};
} // namespace xmrig
bool xmrig::Benchmark::finish(uint64_t totalHashCount)
{
m_reset = true;
m_current = totalHashCount;
if (m_done < m_workers) {
return false;
}
const double dt = (m_doneTime - m_startTime) / 1000.0;
uint64_t checkData = 0;
const uint32_t N = (m_end / 1000000) - 1;
if (((m_algo == Algorithm::RX_0) || (m_algo == Algorithm::RX_WOW)) && ((m_end % 1000000) == 0) && (N < 10)) {
checkData = hashCheck[(m_algo == Algorithm::RX_0) ? 0 : 1][N];
}
const char *color = checkData ? ((m_data == checkData) ? GREEN_BOLD_S : RED_BOLD_S) : BLACK_BOLD_S;
LOG_NOTICE("%s " WHITE_BOLD("benchmark finished in ") CYAN_BOLD("%.3f seconds") WHITE_BOLD_S " hash sum = " CLEAR "%s%016" PRIX64 CLEAR, Tags::bench(), dt, color, m_data);
LOG_INFO("%s " WHITE_BOLD("press ") MAGENTA_BOLD("Ctrl+C") WHITE_BOLD(" to exit"), Tags::bench());
return true;
}
void xmrig::Benchmark::start()
{
m_startTime = Chrono::steadyMSecs();
}
void xmrig::Benchmark::printProgress() const
{
if (!m_startTime || !m_current) {
return;
}
const double dt = (Chrono::steadyMSecs() - m_startTime) / 1000.0;
const double percent = static_cast<double>(m_current) / m_end * 100.0;
LOG_NOTICE("%s " MAGENTA_BOLD("%5.2f%% ") CYAN_BOLD("%" PRIu64) CYAN("/%" PRIu64) BLACK_BOLD(" (%.3fs)"), Tags::bench(), percent, m_current, m_end, dt);
}
void xmrig::Benchmark::tick(IWorker *worker)
{
if (m_reset) {
m_data = 0;
m_done = 0;
m_reset = false;
}
const uint64_t doneTime = worker->benchDoneTime();
if (!doneTime) {
return;
}
++m_done;
m_data ^= worker->benchData();
m_doneTime = std::max(doneTime, m_doneTime);
}

View file

@ -0,0 +1,62 @@
/* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_BENCHMARK_H
#define XMRIG_BENCHMARK_H
#include "base/tools/Object.h"
#include "base/crypto/Algorithm.h"
namespace xmrig {
class IWorker;
class Benchmark
{
public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(Benchmark)
Benchmark(uint32_t end, const Algorithm &algo, size_t workers) : m_algo(algo), m_workers(workers), m_end(end) {}
~Benchmark() = default;
bool finish(uint64_t totalHashCount);
void printProgress() const;
void start();
void tick(IWorker *worker);
private:
bool m_reset = false;
const Algorithm m_algo = Algorithm::RX_0;
const size_t m_workers = 0;
const uint64_t m_end = 0;
uint32_t m_done = 0;
uint64_t m_current = 0;
uint64_t m_data = 0;
uint64_t m_doneTime = 0;
uint64_t m_startTime = 0;
};
} // namespace xmrig
#endif /* XMRIG_BENCHMARK_H */

View file

@ -48,13 +48,13 @@ inline static const char *format(double h, char *buf, size_t size)
xmrig::Hashrate::Hashrate(size_t threads) :
m_threads(threads)
m_threads(threads + 1)
{
m_counts = new uint64_t*[threads];
m_timestamps = new uint64_t*[threads];
m_top = new uint32_t[threads];
m_counts = new uint64_t*[m_threads];
m_timestamps = new uint64_t*[m_threads];
m_top = new uint32_t[m_threads];
for (size_t i = 0; i < threads; i++) {
for (size_t i = 0; i < m_threads; i++) {
m_counts[i] = new uint64_t[kBucketSize]();
m_timestamps[i] = new uint64_t[kBucketSize]();
m_top[i] = 0;
@ -77,17 +77,8 @@ xmrig::Hashrate::~Hashrate()
double xmrig::Hashrate::calc(size_t ms) const
{
double result = 0.0;
double data;
for (size_t i = 0; i < m_threads; ++i) {
data = calc(i, ms);
if (std::isnormal(data)) {
result += data;
}
}
return result;
const double data = calc(0, ms);
return std::isnormal(data) ? data : 0.0;
}
@ -102,7 +93,7 @@ double xmrig::Hashrate::calc(size_t threadId, size_t ms) const
uint64_t earliestStamp = 0;
bool haveFullSet = false;
const uint64_t timeStampLimit = xmrig::Chrono::highResolutionMSecs() - ms;
const uint64_t timeStampLimit = xmrig::Chrono::steadyMSecs() - ms;
uint64_t* timestamps = m_timestamps[threadId];
uint64_t* counts = m_counts[threadId];
@ -183,9 +174,9 @@ rapidjson::Value xmrig::Hashrate::toJSON(size_t threadId, rapidjson::Document &d
auto &allocator = doc.GetAllocator();
Value out(kArrayType);
out.PushBack(normalize(calc(threadId, ShortInterval)), allocator);
out.PushBack(normalize(calc(threadId, MediumInterval)), allocator);
out.PushBack(normalize(calc(threadId, LargeInterval)), allocator);
out.PushBack(normalize(calc(threadId + 1, ShortInterval)), allocator);
out.PushBack(normalize(calc(threadId + 1, MediumInterval)), allocator);
out.PushBack(normalize(calc(threadId + 1, LargeInterval)), allocator);
return out;
}

View file

@ -0,0 +1,63 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "backend/common/HashrateInterpolator.h"
uint64_t xmrig::HashrateInterpolator::interpolate(uint64_t timeStamp) const
{
timeStamp -= LagMS;
std::lock_guard<std::mutex> l(m_lock);
const size_t N = m_data.size();
if (N < 2) {
return 0;
}
for (size_t i = 0; i < N - 1; ++i) {
const auto& a = m_data[i];
const auto& b = m_data[i + 1];
if (a.second <= timeStamp && timeStamp <= b.second) {
return a.first + static_cast<int64_t>(b.first - a.first) * (timeStamp - a.second) / (b.second - a.second);
}
}
return 0;
}
void xmrig::HashrateInterpolator::addDataPoint(uint64_t count, uint64_t timeStamp)
{
std::lock_guard<std::mutex> l(m_lock);
// Clean up old data
while (!m_data.empty() && (timeStamp - m_data.front().second > LagMS * 2)) {
m_data.pop_front();
}
m_data.emplace_back(count, timeStamp);
}

View file

@ -0,0 +1,57 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_HASHRATE_INTERPOLATOR_H
#define XMRIG_HASHRATE_INTERPOLATOR_H
#include <mutex>
#include <deque>
#include <utility>
namespace xmrig {
class HashrateInterpolator
{
public:
enum {
LagMS = 4000,
};
uint64_t interpolate(uint64_t timeStamp) const;
void addDataPoint(uint64_t count, uint64_t timeStamp);
private:
// Buffer of hashrate counters, used for linear interpolation of past data
mutable std::mutex m_lock;
std::deque<std::pair<uint64_t, uint64_t>> m_data;
};
} // namespace xmrig
#endif /* XMRIG_HASHRATE_INTERPOLATOR_H */

View file

@ -32,9 +32,7 @@
xmrig::Worker::Worker(size_t id, int64_t affinity, int priority) :
m_affinity(affinity),
m_id(id),
m_hashCount(0),
m_timestamp(0)
m_id(id)
{
m_node = VirtualMemory::bindToNUMANode(affinity);
@ -45,6 +43,23 @@ xmrig::Worker::Worker(size_t id, int64_t affinity, int priority) :
void xmrig::Worker::storeStats()
{
m_hashCount.store(m_count, std::memory_order_relaxed);
m_timestamp.store(Chrono::highResolutionMSecs(), std::memory_order_relaxed);
// Get index which is unused now
const uint32_t index = m_index.load(std::memory_order_relaxed) ^ 1;
// Fill in the data for that index
m_hashCount[index] = m_count;
m_timestamp[index] = Chrono::steadyMSecs();
// Switch to that index
// All data will be in memory by the time it completes thanks to std::memory_order_seq_cst
m_index.fetch_xor(1, std::memory_order_seq_cst);
}
void xmrig::Worker::getHashrateData(uint64_t& hashCount, uint64_t& timeStamp) const
{
const uint32_t index = m_index.load(std::memory_order_relaxed);
hashCount = m_hashCount[index];
timeStamp = m_timestamp[index];
}

View file

@ -44,19 +44,31 @@ public:
inline const VirtualMemory *memory() const override { return nullptr; }
inline size_t id() const override { return m_id; }
inline uint64_t hashCount() const override { return m_hashCount.load(std::memory_order_relaxed); }
inline uint64_t timestamp() const override { return m_timestamp.load(std::memory_order_relaxed); }
inline uint64_t rawHashes() const override { return m_count; }
inline void jobEarlyNotification(const Job&) override {}
void getHashrateData(uint64_t& hashCount, uint64_t& timeStamp) const override;
# ifdef XMRIG_FEATURE_BENCHMARK
inline uint64_t benchData() const override { return m_benchData; }
inline uint64_t benchDoneTime() const override { return m_benchDoneTime; }
# endif
protected:
void storeStats();
const int64_t m_affinity;
const size_t m_id;
std::atomic<uint64_t> m_hashCount;
std::atomic<uint64_t> m_timestamp;
uint32_t m_node = 0;
uint64_t m_count = 0;
std::atomic<uint32_t> m_index = {};
uint32_t m_node = 0;
uint64_t m_count = 0;
uint64_t m_hashCount[2] = {};
uint64_t m_timestamp[2] = {};
# ifdef XMRIG_FEATURE_BENCHMARK
uint64_t m_benchData = 0;
uint64_t m_benchDoneTime = 0;
# endif
};

View file

@ -68,7 +68,7 @@ public:
{
m_rounds[index()]++;
if ((m_rounds[index()] % rounds) == 0) {
if ((m_rounds[index()] & (rounds - 1)) == 0) {
for (size_t i = 0; i < N; ++i) {
if (!Nonce::next(index(), nonce(i), rounds * roundSize, nonceMask())) {
return false;
@ -130,7 +130,7 @@ inline bool xmrig::WorkerJob<1>::nextRound(uint32_t rounds, uint32_t roundSize)
uint32_t* n = nonce();
if ((m_rounds[index()] % rounds) == 0) {
if ((m_rounds[index()] & (rounds - 1)) == 0) {
if (!Nonce::next(index(), n, rounds * roundSize, nonceMask())) {
return false;
}

View file

@ -6,8 +6,8 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -29,7 +29,11 @@
#include "backend/common/Workers.h"
#include "backend/cpu/CpuWorker.h"
#include "base/io/log/Log.h"
#include "base/io/log/Tags.h"
#include "base/net/stratum/Pool.h"
#include "base/tools/Chrono.h"
#include "base/tools/Object.h"
#include "core/Miner.h"
#ifdef XMRIG_FEATURE_OPENCL
@ -42,6 +46,11 @@
#endif
#ifdef XMRIG_FEATURE_BENCHMARK
# include "backend/common/Benchmark.h"
#endif
namespace xmrig {
@ -51,17 +60,12 @@ public:
XMRIG_DISABLE_COPY_MOVE(WorkersPrivate)
WorkersPrivate() = default;
WorkersPrivate() = default;
~WorkersPrivate() = default;
inline ~WorkersPrivate()
{
delete hashrate;
}
Hashrate *hashrate = nullptr;
IBackend *backend = nullptr;
IBackend *backend = nullptr;
std::shared_ptr<Benchmark> benchmark;
std::shared_ptr<Hashrate> hashrate;
};
@ -83,10 +87,77 @@ xmrig::Workers<T>::~Workers()
}
template<class T>
xmrig::Benchmark *xmrig::Workers<T>::benchmark() const
{
return d_ptr->benchmark.get();
}
template<class T>
static void getHashrateData(xmrig::IWorker* worker, uint64_t& hashCount, uint64_t& timeStamp)
{
worker->getHashrateData(hashCount, timeStamp);
}
template<>
void getHashrateData<xmrig::CpuLaunchData>(xmrig::IWorker* worker, uint64_t& hashCount, uint64_t&)
{
hashCount = worker->rawHashes();
}
template<class T>
bool xmrig::Workers<T>::tick(uint64_t)
{
if (!d_ptr->hashrate) {
return true;
}
uint64_t ts = Chrono::steadyMSecs();
bool totalAvailable = true;
uint64_t totalHashCount = 0;
for (Thread<T> *handle : m_workers) {
IWorker *worker = handle->worker();
if (worker) {
uint64_t hashCount;
getHashrateData<T>(worker, hashCount, ts);
d_ptr->hashrate->add(handle->id() + 1, hashCount, ts);
const uint64_t n = worker->rawHashes();
if (n == 0) {
totalAvailable = false;
}
totalHashCount += n;
# ifdef XMRIG_FEATURE_BENCHMARK
if (d_ptr->benchmark) {
d_ptr->benchmark->tick(worker);
}
# endif
}
}
if (totalAvailable) {
d_ptr->hashrate->add(0, totalHashCount, Chrono::steadyMSecs());
}
# ifdef XMRIG_FEATURE_BENCHMARK
if (d_ptr->benchmark && d_ptr->benchmark->finish(totalHashCount)) {
return false;
}
# endif
return true;
}
template<class T>
const xmrig::Hashrate *xmrig::Workers<T>::hashrate() const
{
return d_ptr->hashrate;
return d_ptr->hashrate.get();
}
@ -100,21 +171,35 @@ void xmrig::Workers<T>::setBackend(IBackend *backend)
template<class T>
void xmrig::Workers<T>::start(const std::vector<T> &data)
{
# ifdef XMRIG_FEATURE_BENCHMARK
if (!data.empty() && data.front().benchSize) {
d_ptr->benchmark = std::make_shared<Benchmark>(data.front().benchSize, data.front().algorithm, data.size());
}
# endif
for (const T &item : data) {
m_workers.push_back(new Thread<T>(d_ptr->backend, m_workers.size(), item));
}
d_ptr->hashrate = new Hashrate(m_workers.size());
d_ptr->hashrate = std::make_shared<Hashrate>(m_workers.size());
Nonce::touch(T::backend());
for (Thread<T> *worker : m_workers) {
worker->start(Workers<T>::onReady);
// This sleep is important for optimal caching!
// Threads must allocate scratchpads in order so that adjacent cores will use adjacent scratchpads
// Sub-optimal caching can result in up to 0.5% hashrate penalty
std::this_thread::sleep_for(std::chrono::milliseconds(20));
# ifdef XMRIG_FEATURE_BENCHMARK
if (!d_ptr->benchmark)
# endif
{
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
}
# ifdef XMRIG_FEATURE_BENCHMARK
if (d_ptr->benchmark) {
d_ptr->benchmark->start();
}
# endif
}
@ -130,25 +215,7 @@ void xmrig::Workers<T>::stop()
m_workers.clear();
Nonce::touch(T::backend());
delete d_ptr->hashrate;
d_ptr->hashrate = nullptr;
}
template<class T>
void xmrig::Workers<T>::tick(uint64_t)
{
if (!d_ptr->hashrate) {
return;
}
for (Thread<T> *handle : m_workers) {
if (!handle->worker()) {
continue;
}
d_ptr->hashrate->add(handle->id(), handle->worker()->hashCount(), handle->worker()->timestamp());
}
d_ptr->hashrate.reset();
}

View file

@ -6,8 +6,8 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -29,7 +29,6 @@
#include "backend/common/Thread.h"
#include "backend/cpu/CpuLaunchData.h"
#include "base/tools/Object.h"
#ifdef XMRIG_FEATURE_OPENCL
@ -48,6 +47,7 @@ namespace xmrig {
class Hashrate;
class WorkersPrivate;
class Job;
class Benchmark;
template<class T>
@ -59,12 +59,13 @@ public:
Workers();
~Workers();
Benchmark *benchmark() const;
bool tick(uint64_t ticks);
const Hashrate *hashrate() const;
void jobEarlyNotification(const Job&);
void setBackend(IBackend *backend);
void start(const std::vector<T> &data);
void stop();
void tick(uint64_t ticks);
void jobEarlyNotification(const Job&);
private:
static IWorker *create(Thread<T> *handle);

View file

@ -1,5 +1,6 @@
set(HEADERS_BACKEND_COMMON
src/backend/common/Hashrate.h
src/backend/common/HashrateInterpolator.h
src/backend/common/Tags.h
src/backend/common/interfaces/IBackend.h
src/backend/common/interfaces/IRxListener.h
@ -15,7 +16,13 @@ set(HEADERS_BACKEND_COMMON
set(SOURCES_BACKEND_COMMON
src/backend/common/Hashrate.cpp
src/backend/common/HashrateInterpolator.cpp
src/backend/common/Threads.cpp
src/backend/common/Worker.cpp
src/backend/common/Workers.cpp
)
if (WITH_RANDOMX AND WITH_BENCHMARK)
list(APPEND HEADERS_BACKEND_COMMON src/backend/common/Benchmark.h)
list(APPEND SOURCES_BACKEND_COMMON src/backend/common/Benchmark.cpp)
endif()

View file

@ -36,6 +36,7 @@ namespace xmrig {
class Algorithm;
class Benchmark;
class Hashrate;
class IApiRequest;
class IWorker;
@ -60,12 +61,17 @@ public:
virtual void setJob(const Job &job) = 0;
virtual void start(IWorker *worker, bool ready) = 0;
virtual void stop() = 0;
virtual void tick(uint64_t ticks) = 0;
virtual bool tick(uint64_t ticks) = 0;
# ifdef XMRIG_FEATURE_API
virtual rapidjson::Value toJSON(rapidjson::Document &doc) const = 0;
virtual void handleRequest(IApiRequest &request) = 0;
# endif
# ifdef XMRIG_FEATURE_BENCHMARK
virtual Benchmark *benchmark() const = 0;
virtual void printBenchProgress() const = 0;
# endif
};

View file

@ -42,14 +42,19 @@ class IWorker
public:
virtual ~IWorker() = default;
virtual bool selfTest() = 0;
virtual const VirtualMemory *memory() const = 0;
virtual size_t id() const = 0;
virtual size_t intensity() const = 0;
virtual uint64_t hashCount() const = 0;
virtual uint64_t timestamp() const = 0;
virtual void start() = 0;
virtual void jobEarlyNotification(const Job&) = 0;
virtual bool selfTest() = 0;
virtual const VirtualMemory *memory() const = 0;
virtual size_t id() const = 0;
virtual size_t intensity() const = 0;
virtual uint64_t rawHashes() const = 0;
virtual void getHashrateData(uint64_t&, uint64_t&) const = 0;
virtual void start() = 0;
virtual void jobEarlyNotification(const Job&) = 0;
# ifdef XMRIG_FEATURE_BENCHMARK
virtual uint64_t benchData() const = 0;
virtual uint64_t benchDoneTime() const = 0;
# endif
};

View file

@ -55,6 +55,11 @@
#endif
#ifdef XMRIG_FEATURE_BENCHMARK
# include "backend/common/Benchmark.h"
#endif
namespace xmrig {
@ -304,9 +309,9 @@ void xmrig::CpuBackend::printHashrate(bool details)
Log::print("| %8zu | %8" PRId64 " | %7s | %7s | %7s |",
i,
data.affinity,
Hashrate::format(hashrate()->calc(i, Hashrate::ShortInterval), num, sizeof num / 3),
Hashrate::format(hashrate()->calc(i, Hashrate::MediumInterval), num + 8, sizeof num / 3),
Hashrate::format(hashrate()->calc(i, Hashrate::LargeInterval), num + 8 * 2, sizeof num / 3)
Hashrate::format(hashrate()->calc(i + 1, Hashrate::ShortInterval), num, sizeof num / 3),
Hashrate::format(hashrate()->calc(i + 1, Hashrate::MediumInterval), num + 8, sizeof num / 3),
Hashrate::format(hashrate()->calc(i + 1, Hashrate::LargeInterval), num + 8 * 2, sizeof num / 3)
);
i++;
@ -335,7 +340,7 @@ void xmrig::CpuBackend::setJob(const Job &job)
const CpuConfig &cpu = d_ptr->controller->config()->cpu();
std::vector<CpuLaunchData> threads = cpu.get(d_ptr->controller->miner(), job.algorithm());
std::vector<CpuLaunchData> threads = cpu.get(d_ptr->controller->miner(), job.algorithm(), d_ptr->controller->config()->pools().benchSize());
if (!d_ptr->threads.empty() && d_ptr->threads.size() == threads.size() && std::equal(d_ptr->threads.begin(), d_ptr->threads.end(), threads.begin())) {
return;
}
@ -387,9 +392,9 @@ void xmrig::CpuBackend::stop()
}
void xmrig::CpuBackend::tick(uint64_t ticks)
bool xmrig::CpuBackend::tick(uint64_t ticks)
{
d_ptr->workers.tick(ticks);
return d_ptr->workers.tick(ticks);
}
@ -459,3 +464,20 @@ void xmrig::CpuBackend::handleRequest(IApiRequest &request)
}
}
#endif
#ifdef XMRIG_FEATURE_BENCHMARK
xmrig::Benchmark *xmrig::CpuBackend::benchmark() const
{
return d_ptr->workers.benchmark();
}
void xmrig::CpuBackend::printBenchProgress() const
{
auto benchmark = d_ptr->workers.benchmark();
if (benchmark) {
benchmark->printProgress();
}
}
#endif

View file

@ -63,13 +63,18 @@ protected:
void setJob(const Job &job) override;
void start(IWorker *worker, bool ready) override;
void stop() override;
void tick(uint64_t ticks) override;
bool tick(uint64_t ticks) override;
# ifdef XMRIG_FEATURE_API
rapidjson::Value toJSON(rapidjson::Document &doc) const override;
void handleRequest(IApiRequest &request) override;
# endif
# ifdef XMRIG_FEATURE_BENCHMARK
Benchmark *benchmark() const override;
void printBenchProgress() const override;
# endif
private:
CpuBackendPrivate *d_ptr;
};

View file

@ -34,25 +34,27 @@
namespace xmrig {
static const char *kEnabled = "enabled";
static const char *kHugePages = "huge-pages";
static const char *kHwAes = "hw-aes";
static const char *kMaxThreadsHint = "max-threads-hint";
static const char *kMemoryPool = "memory-pool";
static const char *kPriority = "priority";
static const char *kYield = "yield";
const char *CpuConfig::kEnabled = "enabled";
const char *CpuConfig::kField = "cpu";
const char *CpuConfig::kHugePages = "huge-pages";
const char *CpuConfig::kHugePagesJit = "huge-pages-jit";
const char *CpuConfig::kHwAes = "hw-aes";
const char *CpuConfig::kMaxThreadsHint = "max-threads-hint";
const char *CpuConfig::kMemoryPool = "memory-pool";
const char *CpuConfig::kPriority = "priority";
const char *CpuConfig::kYield = "yield";
#ifdef XMRIG_FEATURE_ASM
static const char *kAsm = "asm";
const char *CpuConfig::kAsm = "asm";
#endif
#ifdef XMRIG_ALGO_ARGON2
static const char *kArgon2Impl = "argon2-impl";
const char *CpuConfig::kArgon2Impl = "argon2-impl";
#endif
#ifdef XMRIG_ALGO_ASTROBWT
static const char* kAstroBWTMaxSize = "astrobwt-max-size";
static const char* kAstroBWTAVX2 = "astrobwt-avx2";
const char *CpuConfig::kAstroBWTMaxSize = "astrobwt-max-size";
const char *CpuConfig::kAstroBWTAVX2 = "astrobwt-avx2";
#endif
@ -76,6 +78,7 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const
obj.AddMember(StringRef(kEnabled), m_enabled, allocator);
obj.AddMember(StringRef(kHugePages), m_hugePages, allocator);
obj.AddMember(StringRef(kHugePagesJit), m_hugePagesJit, allocator);
obj.AddMember(StringRef(kHwAes), m_aes == AES_AUTO ? Value(kNullType) : Value(m_aes == AES_HW), allocator);
obj.AddMember(StringRef(kPriority), priority() != -1 ? Value(priority()) : Value(kNullType), allocator);
obj.AddMember(StringRef(kMemoryPool), m_memoryPool < 1 ? Value(m_memoryPool < 0) : Value(m_memoryPool), allocator);
@ -110,7 +113,7 @@ size_t xmrig::CpuConfig::memPoolSize() const
}
std::vector<xmrig::CpuLaunchData> xmrig::CpuConfig::get(const Miner *miner, const Algorithm &algorithm) const
std::vector<xmrig::CpuLaunchData> xmrig::CpuConfig::get(const Miner *miner, const Algorithm &algorithm, uint32_t benchSize) const
{
std::vector<CpuLaunchData> out;
const CpuThreads &threads = m_threads.get(algorithm);
@ -122,7 +125,7 @@ std::vector<xmrig::CpuLaunchData> xmrig::CpuConfig::get(const Miner *miner, cons
out.reserve(threads.count());
for (const CpuThread &thread : threads.data()) {
out.emplace_back(miner, algorithm, *this, thread);
out.emplace_back(miner, algorithm, *this, thread, benchSize);
}
return out;
@ -132,10 +135,11 @@ std::vector<xmrig::CpuLaunchData> xmrig::CpuConfig::get(const Miner *miner, cons
void xmrig::CpuConfig::read(const rapidjson::Value &value)
{
if (value.IsObject()) {
m_enabled = Json::getBool(value, kEnabled, m_enabled);
m_hugePages = Json::getBool(value, kHugePages, m_hugePages);
m_limit = Json::getUint(value, kMaxThreadsHint, m_limit);
m_yield = Json::getBool(value, kYield, m_yield);
m_enabled = Json::getBool(value, kEnabled, m_enabled);
m_hugePages = Json::getBool(value, kHugePages, m_hugePages);
m_hugePagesJit = Json::getBool(value, kHugePagesJit, m_hugePagesJit);
m_limit = Json::getUint(value, kMaxThreadsHint, m_limit);
m_yield = Json::getBool(value, kYield, m_yield);
setAesMode(Json::getValue(value, kHwAes));
setPriority(Json::getInt(value, kPriority, -1));

View file

@ -44,16 +44,40 @@ public:
AES_SOFT
};
static const char *kEnabled;
static const char *kField;
static const char *kHugePages;
static const char *kHugePagesJit;
static const char *kHwAes;
static const char *kMaxThreadsHint;
static const char *kMemoryPool;
static const char *kPriority;
static const char *kYield;
# ifdef XMRIG_FEATURE_ASM
static const char *kAsm;
# endif
# ifdef XMRIG_ALGO_ARGON2
static const char *kArgon2Impl;
# endif
# ifdef XMRIG_ALGO_ASTROBWT
static const char *kAstroBWTMaxSize;
static const char *kAstroBWTAVX2;
# endif
CpuConfig() = default;
bool isHwAES() const;
rapidjson::Value toJSON(rapidjson::Document &doc) const;
size_t memPoolSize() const;
std::vector<CpuLaunchData> get(const Miner *miner, const Algorithm &algorithm) const;
std::vector<CpuLaunchData> get(const Miner *miner, const Algorithm &algorithm, uint32_t benchSize) const;
void read(const rapidjson::Value &value);
inline bool isEnabled() const { return m_enabled; }
inline bool isHugePages() const { return m_hugePages; }
inline bool isHugePagesJit() const { return m_hugePagesJit; }
inline bool isShouldSave() const { return m_shouldSave; }
inline bool isYield() const { return m_yield; }
inline const Assembly &assembly() const { return m_assembly; }
@ -76,6 +100,7 @@ private:
bool m_astrobwtAVX2 = false;
bool m_enabled = true;
bool m_hugePages = true;
bool m_hugePagesJit = false;
bool m_shouldSave = false;
bool m_yield = true;
int m_astrobwtMaxSize = 550;

View file

@ -157,7 +157,7 @@ size_t inline generate<Algorithm::RANDOM_X>(Threads<CpuThreads> &threads, uint32
template<>
size_t inline generate<Algorithm::ARGON2>(Threads<CpuThreads> &threads, uint32_t limit)
{
return generate("argon2", threads, Algorithm::AR2_CHUKWA, limit);
return generate("argon2", threads, Algorithm::AR2_CHUKWA_V2, limit);
}
#endif

View file

@ -32,7 +32,7 @@
#include <algorithm>
xmrig::CpuLaunchData::CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread) :
xmrig::CpuLaunchData::CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread, uint32_t benchSize) :
algorithm(algorithm),
assembly(config.assembly()),
astrobwtAVX2(config.astrobwtAVX2()),
@ -43,6 +43,7 @@ xmrig::CpuLaunchData::CpuLaunchData(const Miner *miner, const Algorithm &algorit
priority(config.priority()),
affinity(thread.affinity()),
miner(miner),
benchSize(benchSize),
intensity(std::min<uint32_t>(thread.intensity(), algorithm.maxIntensity()))
{
}

View file

@ -44,12 +44,12 @@ class Miner;
class CpuLaunchData
{
public:
CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread);
CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread, uint32_t benchSize);
bool isEqual(const CpuLaunchData &other) const;
CnHash::AlgoVariant av() const;
inline constexpr static Nonce::Backend backend() { return Nonce::CPU; }
inline constexpr static Nonce::Backend backend() { return Nonce::CPU; }
inline bool operator!=(const CpuLaunchData &other) const { return !isEqual(other); }
inline bool operator==(const CpuLaunchData &other) const { return isEqual(other); }
@ -66,6 +66,7 @@ public:
const int priority;
const int64_t affinity;
const Miner *miner;
const uint32_t benchSize;
const uint32_t intensity;
};

View file

@ -29,6 +29,7 @@
#include "backend/cpu/CpuWorker.h"
#include "base/tools/Chrono.h"
#include "core/Miner.h"
#include "crypto/cn/CnCtx.h"
#include "crypto/cn/CryptoNight_test.h"
@ -57,9 +58,9 @@ static constexpr uint32_t kReserveCount = 32768;
template<size_t N>
inline bool nextRound(WorkerJob<N> &job)
inline bool nextRound(WorkerJob<N> &job, uint32_t benchSize)
{
if (!job.nextRound(kReserveCount, 1)) {
if (!job.nextRound(benchSize ? 1 : kReserveCount, 1)) {
JobResults::done(job.currentJob());
return false;
@ -84,6 +85,7 @@ xmrig::CpuWorker<N>::CpuWorker(size_t id, const CpuLaunchData &data) :
m_av(data.av()),
m_astrobwtMaxSize(data.astrobwtMaxSize * 1000),
m_miner(data.miner),
m_benchSize(data.benchSize),
m_ctx()
{
m_memory = new VirtualMemory(m_algorithm.l3() * N, data.hugePages, false, true, m_node);
@ -191,6 +193,7 @@ bool xmrig::CpuWorker<N>::selfTest()
# ifdef XMRIG_ALGO_ARGON2
if (m_algorithm.family() == Algorithm::ARGON2) {
return verify(Algorithm::AR2_CHUKWA, argon2_chukwa_test_out) &&
verify(Algorithm::AR2_CHUKWA_V2, argon2_chukwa_v2_test_out) &&
verify(Algorithm::AR2_WRKZ, argon2_wrkz_test_out);
}
# endif
@ -222,23 +225,12 @@ void xmrig::CpuWorker<N>::start()
consumeJob();
}
uint64_t storeStatsMask = 7;
# ifdef XMRIG_ALGO_RANDOMX
bool first = true;
uint64_t tempHash[8] = {};
// RandomX is faster, we don't need to store stats so often
if (m_job.currentJob().algorithm().family() == Algorithm::RANDOM_X) {
storeStatsMask = 63;
}
alignas(16) uint64_t tempHash[8] = {};
# endif
while (!Nonce::isOutdated(Nonce::CPU, m_job.sequence())) {
if ((m_count & storeStatsMask) == 0) {
storeStats();
}
const Job &job = m_job.currentJob();
if (job.algorithm().l3() != m_algorithm.l3()) {
@ -260,7 +252,7 @@ void xmrig::CpuWorker<N>::start()
randomx_calculate_hash_first(m_vm, tempHash, m_job.blob(), job.size(), job.algorithm());
}
if (!nextRound(m_job)) {
if (!nextRound(m_job, m_benchSize)) {
break;
}
@ -280,14 +272,28 @@ void xmrig::CpuWorker<N>::start()
fn(job.algorithm())(m_job.blob(), job.size(), m_hash, m_ctx, job.height());
}
if (!nextRound(m_job)) {
if (!nextRound(m_job, m_benchSize)) {
break;
};
}
if (valid) {
for (size_t i = 0; i < N; ++i) {
if (*reinterpret_cast<uint64_t*>(m_hash + (i * 32) + 24) < job.target()) {
const uint64_t value = *reinterpret_cast<uint64_t*>(m_hash + (i * 32) + 24);
# ifdef XMRIG_FEATURE_BENCHMARK
if (m_benchSize) {
if (current_job_nonces[i] < m_benchSize) {
m_benchData ^= value;
}
else {
m_benchDoneTime = Chrono::steadyMSecs();
return;
}
}
else
# endif
if (value < job.target()) {
JobResults::submit(job, current_job_nonces[i], m_hash + (i * 32));
}
}
@ -384,7 +390,7 @@ void xmrig::CpuWorker<N>::consumeJob()
return;
}
m_job.add(m_miner->job(), kReserveCount, Nonce::CPU);
m_job.add(m_miner->job(), m_benchSize ? 1 : kReserveCount, Nonce::CPU);
# ifdef XMRIG_ALGO_RANDOMX
if (m_job.currentJob().algorithm().family() == Algorithm::RANDOM_X) {

View file

@ -73,6 +73,7 @@ private:
void allocateCnCtx();
void consumeJob();
alignas(16) uint8_t m_hash[N * 32]{ 0 };
const Algorithm m_algorithm;
const Assembly m_assembly;
const bool m_astrobwtAVX2;
@ -81,8 +82,8 @@ private:
const CnHash::AlgoVariant m_av;
const int m_astrobwtMaxSize;
const Miner *m_miner;
const uint32_t m_benchSize;
cryptonight_ctx *m_ctx[N];
uint8_t m_hash[N * 32]{ 0 };
VirtualMemory *m_memory = nullptr;
WorkerJob<N> m_job;

View file

@ -409,9 +409,9 @@ void xmrig::CudaBackend::printHashrate(bool details)
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(hashrate()->calc(i + 1, Hashrate::ShortInterval) * scale, num, sizeof num / 3),
Hashrate::format(hashrate()->calc(i + 1, Hashrate::MediumInterval) * scale, num + 16, sizeof num / 3),
Hashrate::format(hashrate()->calc(i + 1, Hashrate::LargeInterval) * scale, num + 16 * 2, sizeof num / 3),
data.device.index(),
data.device.topology().toString().data(),
data.device.name().data()
@ -421,9 +421,9 @@ void xmrig::CudaBackend::printHashrate(bool details)
}
Log::print(WHITE_BOLD_S "| - | - | %8s | %8s | %8s |",
Hashrate::format(hashrate()->calc(Hashrate::ShortInterval) * scale, num, sizeof num / 3),
Hashrate::format(hashrate()->calc(Hashrate::MediumInterval) * scale, num + 16, sizeof num / 3),
Hashrate::format(hashrate()->calc(Hashrate::LargeInterval) * scale, num + 16 * 2, sizeof num / 3)
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)
);
}
@ -501,9 +501,9 @@ void xmrig::CudaBackend::stop()
}
void xmrig::CudaBackend::tick(uint64_t ticks)
bool xmrig::CudaBackend::tick(uint64_t ticks)
{
d_ptr->workers.tick(ticks);
return d_ptr->workers.tick(ticks);
}

View file

@ -63,13 +63,18 @@ protected:
void setJob(const Job &job) override;
void start(IWorker *worker, bool ready) override;
void stop() override;
void tick(uint64_t ticks) override;
bool tick(uint64_t ticks) override;
# ifdef XMRIG_FEATURE_API
rapidjson::Value toJSON(rapidjson::Document &doc) const override;
void handleRequest(IApiRequest &request) override;
# endif
# ifdef XMRIG_FEATURE_BENCHMARK
inline Benchmark *benchmark() const override { return nullptr; }
inline void printBenchProgress() const override {}
# endif
private:
CudaBackendPrivate *d_ptr;
};

View file

@ -30,9 +30,9 @@
xmrig::CudaLaunchData::CudaLaunchData(const Miner *miner, const Algorithm &algorithm, const CudaThread &thread, const CudaDevice &device) :
algorithm(algorithm),
miner(miner),
device(device),
thread(thread)
thread(thread),
miner(miner)
{
}

View file

@ -54,9 +54,10 @@ public:
static const char *tag();
const Algorithm algorithm;
const Miner *miner;
const CudaDevice &device;
const CudaThread thread;
const Miner *miner;
const uint32_t benchSize = 0;
};

View file

@ -62,7 +62,6 @@ std::atomic<bool> CudaWorker::ready;
static inline bool isReady() { return !Nonce::isPaused() && CudaWorker::ready; }
static inline uint32_t roundSize(uint32_t intensity) { return kReserveCount / intensity + 1; }
} // namespace xmrig
@ -120,6 +119,12 @@ xmrig::CudaWorker::~CudaWorker()
}
uint64_t xmrig::CudaWorker::rawHashes() const
{
return m_hashrateData.interpolate(Chrono::steadyMSecs());
}
void xmrig::CudaWorker::jobEarlyNotification(const Job& job)
{
if (m_runner) {
@ -170,8 +175,7 @@ void xmrig::CudaWorker::start()
JobResults::submit(m_job.currentJob(), foundNonce, foundCount, m_deviceIndex);
}
const size_t batch_size = intensity();
if (!Nonce::isOutdated(Nonce::CUDA, m_job.sequence()) && !m_job.nextRound(roundSize(batch_size), batch_size)) {
if (!Nonce::isOutdated(Nonce::CUDA, m_job.sequence()) && !m_job.nextRound(1, intensity())) {
JobResults::done(m_job.currentJob());
}
@ -192,8 +196,7 @@ bool xmrig::CudaWorker::consumeJob()
return false;
}
const size_t batch_size = intensity();
m_job.add(m_miner->job(), roundSize(batch_size) * batch_size, Nonce::CUDA);
m_job.add(m_miner->job(), intensity(), Nonce::CUDA);
return m_runner->set(m_job.currentJob(), m_job.blob());
}
@ -207,5 +210,8 @@ void xmrig::CudaWorker::storeStats()
m_count += m_runner ? m_runner->processedHashes() : 0;
const uint64_t timeStamp = Chrono::steadyMSecs();
m_hashrateData.addDataPoint(m_count, timeStamp);
Worker::storeStats();
}

View file

@ -27,6 +27,7 @@
#define XMRIG_CUDAWORKER_H
#include "backend/common/HashrateInterpolator.h"
#include "backend/common/Worker.h"
#include "backend/common/WorkerJob.h"
#include "backend/cuda/CudaLaunchData.h"
@ -49,6 +50,7 @@ public:
~CudaWorker() override;
uint64_t rawHashes() const override;
void jobEarlyNotification(const Job&) override;
static std::atomic<bool> ready;
@ -67,6 +69,8 @@ private:
ICudaRunner *m_runner = nullptr;
WorkerJob<1> m_job;
uint32_t m_deviceIndex;
HashrateInterpolator m_hashrateData;
};

View file

@ -385,9 +385,9 @@ void xmrig::OclBackend::printHashrate(bool details)
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(hashrate()->calc(i + 1, Hashrate::ShortInterval) * scale, num, sizeof num / 3),
Hashrate::format(hashrate()->calc(i + 1, Hashrate::MediumInterval) * scale, num + 16, sizeof num / 3),
Hashrate::format(hashrate()->calc(i + 1, Hashrate::LargeInterval) * scale, num + 16 * 2, sizeof num / 3),
data.device.index(),
data.device.topology().toString().data(),
data.device.printableName().data()
@ -397,9 +397,9 @@ void xmrig::OclBackend::printHashrate(bool details)
}
Log::print(WHITE_BOLD_S "| - | - | %8s | %8s | %8s |",
Hashrate::format(hashrate()->calc(Hashrate::ShortInterval) * scale, num, sizeof num / 3),
Hashrate::format(hashrate()->calc(Hashrate::MediumInterval) * scale, num + 16, sizeof num / 3),
Hashrate::format(hashrate()->calc(Hashrate::LargeInterval) * scale, num + 16 * 2, sizeof num / 3)
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)
);
}
@ -485,9 +485,9 @@ void xmrig::OclBackend::stop()
}
void xmrig::OclBackend::tick(uint64_t ticks)
bool xmrig::OclBackend::tick(uint64_t ticks)
{
d_ptr->workers.tick(ticks);
return d_ptr->workers.tick(ticks);
}

View file

@ -63,13 +63,18 @@ protected:
void setJob(const Job &job) override;
void start(IWorker *worker, bool ready) override;
void stop() override;
void tick(uint64_t ticks) override;
bool tick(uint64_t ticks) override;
# ifdef XMRIG_FEATURE_API
rapidjson::Value toJSON(rapidjson::Document &doc) const override;
void handleRequest(IApiRequest &request) override;
# endif
# ifdef XMRIG_FEATURE_BENCHMARK
inline Benchmark *benchmark() const override { return nullptr; }
inline void printBenchProgress() const override {}
# endif
private:
OclBackendPrivate *d_ptr;
};

View file

@ -67,6 +67,7 @@ public:
const OclDevice device;
const OclPlatform platform;
const OclThread thread;
const uint32_t benchSize = 0;
};

View file

@ -60,12 +60,10 @@
namespace xmrig {
static constexpr uint32_t kReserveCount = 32768;
std::atomic<bool> OclWorker::ready;
static inline bool isReady() { return !Nonce::isPaused() && OclWorker::ready; }
static inline uint32_t roundSize(uint32_t intensity) { return kReserveCount / intensity + 1; }
static inline void printError(size_t id, const char *error)
@ -82,7 +80,6 @@ xmrig::OclWorker::OclWorker(size_t id, const OclLaunchData &data) :
Worker(id, data.affinity, -1),
m_algorithm(data.algorithm),
m_miner(data.miner),
m_intensity(data.thread.intensity()),
m_sharedData(OclSharedState::get(data.device.index())),
m_deviceIndex(data.device.index())
{
@ -152,6 +149,12 @@ xmrig::OclWorker::~OclWorker()
}
uint64_t xmrig::OclWorker::rawHashes() const
{
return m_hashrateData.interpolate(Chrono::steadyMSecs());
}
void xmrig::OclWorker::jobEarlyNotification(const Job& job)
{
if (m_runner) {
@ -176,8 +179,6 @@ void xmrig::OclWorker::start()
{
cl_uint results[0x100];
const uint32_t runnerRoundSize = m_runner->roundSize();
while (Nonce::sequence(Nonce::OPENCL) > 0) {
if (!isReady()) {
m_sharedData.setResumeCounter(0);
@ -216,7 +217,7 @@ void xmrig::OclWorker::start()
JobResults::submit(m_job.currentJob(), results, results[0xFF], m_deviceIndex);
}
if (!Nonce::isOutdated(Nonce::OPENCL, m_job.sequence()) && !m_job.nextRound(roundSize(runnerRoundSize), runnerRoundSize)) {
if (!Nonce::isOutdated(Nonce::OPENCL, m_job.sequence()) && !m_job.nextRound(1, intensity())) {
JobResults::done(m_job.currentJob());
}
@ -237,7 +238,7 @@ bool xmrig::OclWorker::consumeJob()
return false;
}
m_job.add(m_miner->job(), roundSize(m_intensity) * m_intensity, Nonce::OPENCL);
m_job.add(m_miner->job(), intensity(), Nonce::OPENCL);
try {
m_runner->set(m_job.currentJob(), m_job.blob());
@ -259,8 +260,11 @@ void xmrig::OclWorker::storeStats(uint64_t t)
}
m_count += m_runner->processedHashes();
const uint64_t timeStamp = Chrono::steadyMSecs();
m_sharedData.setRunTime(Chrono::steadyMSecs() - t);
m_hashrateData.addDataPoint(m_count, timeStamp);
m_sharedData.setRunTime(timeStamp - t);
Worker::storeStats();
}

View file

@ -27,6 +27,7 @@
#define XMRIG_OCLWORKER_H
#include "backend/common/HashrateInterpolator.h"
#include "backend/common/Worker.h"
#include "backend/common/WorkerJob.h"
#include "backend/opencl/OclLaunchData.h"
@ -50,6 +51,7 @@ public:
~OclWorker() override;
uint64_t rawHashes() const override;
void jobEarlyNotification(const Job&) override;
static std::atomic<bool> ready;
@ -65,11 +67,12 @@ private:
const Algorithm m_algorithm;
const Miner *m_miner;
const uint32_t m_intensity;
IOclRunner *m_runner = nullptr;
OclSharedData &m_sharedData;
WorkerJob<1> m_job;
uint32_t m_deviceIndex;
HashrateInterpolator m_hashrateData;
};

View file

@ -20,16 +20,15 @@
#define ALGO_CN_GPU 19
#define ALGO_RX_0 20
#define ALGO_RX_WOW 21
#define ALGO_RX_LOKI 22
#define ALGO_RX_ARQ 23
#define ALGO_RX_SFX 24
#define ALGO_RX_KEVA 25
#define ALGO_RX_ARQ 22
#define ALGO_RX_SFX 23
#define ALGO_RX_KEVA 24
#define ALGO_AR2_CHUKWA 25
#define ALGO_AR2_CHUKWA 26
#define ALGO_AR2_WRKZ 27
#define ALGO_ASTROBWT_DERO 28
#define ALGO_KAWPOW_RVN 29
#define ALGO_RX_DEFYX 30
#define ALGO_RX_XLA 31
#define ALGO_RX_XLA 30
#define FAMILY_UNKNOWN 0
#define FAMILY_CN 1

File diff suppressed because it is too large Load diff

View file

@ -4,8 +4,6 @@
#include "randomx_constants_monero.h"
#elif (ALGO == ALGO_RX_WOW)
#include "randomx_constants_wow.h"
#elif (ALGO == ALGO_RX_LOKI)
#include "randomx_constants_loki.h"
#elif (ALGO == ALGO_RX_ARQ)
#include "randomx_constants_arqma.h"
#elif (ALGO == ALGO_RX_KEVA)

File diff suppressed because it is too large Load diff

View file

@ -1,96 +0,0 @@
/*
Copyright (c) 2019 SChernykh
This file is part of RandomX OpenCL.
RandomX OpenCL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
RandomX OpenCL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with RandomX OpenCL. If not, see <http://www.gnu.org/licenses/>.
*/
//Dataset base size in bytes. Must be a power of 2.
#define RANDOMX_DATASET_BASE_SIZE 2147483648
//Dataset extra size. Must be divisible by 64.
#define RANDOMX_DATASET_EXTRA_SIZE 33554368
//Scratchpad L3 size in bytes. Must be a power of 2.
#define RANDOMX_SCRATCHPAD_L3 2097152
//Scratchpad L2 size in bytes. Must be a power of two and less than or equal to RANDOMX_SCRATCHPAD_L3.
#define RANDOMX_SCRATCHPAD_L2 262144
//Scratchpad L1 size in bytes. Must be a power of two (minimum 64) and less than or equal to RANDOMX_SCRATCHPAD_L2.
#define RANDOMX_SCRATCHPAD_L1 16384
//Jump condition mask size in bits.
#define RANDOMX_JUMP_BITS 8
//Jump condition mask offset in bits. The sum of RANDOMX_JUMP_BITS and RANDOMX_JUMP_OFFSET must not exceed 16.
#define RANDOMX_JUMP_OFFSET 8
//Integer instructions
#define RANDOMX_FREQ_IADD_RS 25
#define RANDOMX_FREQ_IADD_M 7
#define RANDOMX_FREQ_ISUB_R 16
#define RANDOMX_FREQ_ISUB_M 7
#define RANDOMX_FREQ_IMUL_R 16
#define RANDOMX_FREQ_IMUL_M 4
#define RANDOMX_FREQ_IMULH_R 4
#define RANDOMX_FREQ_IMULH_M 1
#define RANDOMX_FREQ_ISMULH_R 4
#define RANDOMX_FREQ_ISMULH_M 1
#define RANDOMX_FREQ_IMUL_RCP 8
#define RANDOMX_FREQ_INEG_R 2
#define RANDOMX_FREQ_IXOR_R 15
#define RANDOMX_FREQ_IXOR_M 5
#define RANDOMX_FREQ_IROR_R 8
#define RANDOMX_FREQ_IROL_R 2
#define RANDOMX_FREQ_ISWAP_R 4
//Floating point instructions
#define RANDOMX_FREQ_FSWAP_R 4
#define RANDOMX_FREQ_FADD_R 16
#define RANDOMX_FREQ_FADD_M 5
#define RANDOMX_FREQ_FSUB_R 16
#define RANDOMX_FREQ_FSUB_M 5
#define RANDOMX_FREQ_FSCAL_R 6
#define RANDOMX_FREQ_FMUL_R 32
#define RANDOMX_FREQ_FDIV_M 4
#define RANDOMX_FREQ_FSQRT_R 6
//Control instructions
#define RANDOMX_FREQ_CBRANCH 16
#define RANDOMX_FREQ_CFROUND 1
//Store instruction
#define RANDOMX_FREQ_ISTORE 16
//No-op instruction
#define RANDOMX_FREQ_NOP 0
#define RANDOMX_DATASET_ITEM_SIZE 64
#define RANDOMX_PROGRAM_SIZE 320
#define HASH_SIZE 64
#define ENTROPY_SIZE (128 + RANDOMX_PROGRAM_SIZE * 8)
#define REGISTERS_SIZE 256
#define IMM_BUF_SIZE (RANDOMX_PROGRAM_SIZE * 4 - REGISTERS_SIZE)
#define IMM_INDEX_COUNT ((IMM_BUF_SIZE / 4) - 2)
#define VM_STATE_SIZE (REGISTERS_SIZE + IMM_BUF_SIZE + RANDOMX_PROGRAM_SIZE * 4)
#define ROUNDING_MODE (RANDOMX_FREQ_CFROUND ? -1 : 0)
// Scratchpad L1/L2/L3 bits
#define LOC_L1 (32 - 14)
#define LOC_L2 (32 - 18)
#define LOC_L3 (32 - 21)