mirror of
https://github.com/xmrig/xmrig.git
synced 2025-12-26 14:02:53 -05:00
Merge xmrig v6.4.0 into master
This commit is contained in:
103
src/backend/common/Benchmark.cpp
Normal file
103
src/backend/common/Benchmark.cpp
Normal 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);
|
||||
}
|
||||
62
src/backend/common/Benchmark.h
Normal file
62
src/backend/common/Benchmark.h
Normal 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 */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
63
src/backend/common/HashrateInterpolator.cpp
Normal file
63
src/backend/common/HashrateInterpolator.cpp
Normal 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);
|
||||
}
|
||||
57
src/backend/common/HashrateInterpolator.h
Normal file
57
src/backend/common/HashrateInterpolator.h
Normal 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 */
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user