mirror of
https://github.com/xmrig/xmrig.git
synced 2024-10-31 05:27:39 +00:00
Restore Hashrate class interface.
This commit is contained in:
parent
bd82b3c852
commit
acf7ec8355
7 changed files with 90 additions and 103 deletions
|
@ -1,12 +1,7 @@
|
||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -24,7 +19,6 @@
|
||||||
|
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cmath>
|
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
@ -75,72 +69,6 @@ xmrig::Hashrate::~Hashrate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double xmrig::Hashrate::calc(size_t ms) const
|
|
||||||
{
|
|
||||||
const double data = calc(0, ms);
|
|
||||||
return std::isnormal(data) ? data : 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
double xmrig::Hashrate::calc(size_t threadId, size_t ms) const
|
|
||||||
{
|
|
||||||
assert(threadId < m_threads);
|
|
||||||
if (threadId >= m_threads) {
|
|
||||||
return nan("");
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t earliestHashCount = 0;
|
|
||||||
uint64_t earliestStamp = 0;
|
|
||||||
bool haveFullSet = false;
|
|
||||||
|
|
||||||
const uint64_t timeStampLimit = xmrig::Chrono::steadyMSecs() - ms;
|
|
||||||
uint64_t* timestamps = m_timestamps[threadId];
|
|
||||||
uint64_t* counts = m_counts[threadId];
|
|
||||||
|
|
||||||
const size_t idx_start = (m_top[threadId] - 1) & kBucketMask;
|
|
||||||
size_t idx = idx_start;
|
|
||||||
|
|
||||||
uint64_t lastestStamp = timestamps[idx];
|
|
||||||
uint64_t lastestHashCnt = counts[idx];
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (timestamps[idx] < timeStampLimit) {
|
|
||||||
haveFullSet = (timestamps[idx] != 0);
|
|
||||||
if (idx != idx_start) {
|
|
||||||
idx = (idx + 1) & kBucketMask;
|
|
||||||
earliestStamp = timestamps[idx];
|
|
||||||
earliestHashCount = counts[idx];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
idx = (idx - 1) & kBucketMask;
|
|
||||||
} while (idx != idx_start);
|
|
||||||
|
|
||||||
if (!haveFullSet || earliestStamp == 0 || lastestStamp == 0) {
|
|
||||||
return nan("");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastestStamp - earliestStamp == 0) {
|
|
||||||
return nan("");
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto hashes = static_cast<double>(lastestHashCnt - earliestHashCount);
|
|
||||||
const auto time = static_cast<double>(lastestStamp - earliestStamp) / 1000.0;
|
|
||||||
|
|
||||||
return hashes / time;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void xmrig::Hashrate::add(size_t threadId, uint64_t count, uint64_t timestamp)
|
|
||||||
{
|
|
||||||
const size_t top = m_top[threadId];
|
|
||||||
m_counts[threadId][top] = count;
|
|
||||||
m_timestamps[threadId][top] = timestamp;
|
|
||||||
|
|
||||||
m_top[threadId] = (top + 1) & kBucketMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char *xmrig::Hashrate::format(double h, char *buf, size_t size)
|
const char *xmrig::Hashrate::format(double h, char *buf, size_t size)
|
||||||
{
|
{
|
||||||
return ::format(h, buf, size);
|
return ::format(h, buf, size);
|
||||||
|
@ -174,10 +102,69 @@ rapidjson::Value xmrig::Hashrate::toJSON(size_t threadId, rapidjson::Document &d
|
||||||
auto &allocator = doc.GetAllocator();
|
auto &allocator = doc.GetAllocator();
|
||||||
|
|
||||||
Value out(kArrayType);
|
Value out(kArrayType);
|
||||||
out.PushBack(normalize(calc(threadId + 1, ShortInterval)), allocator);
|
out.PushBack(normalize(calc(threadId, ShortInterval)), allocator);
|
||||||
out.PushBack(normalize(calc(threadId + 1, MediumInterval)), allocator);
|
out.PushBack(normalize(calc(threadId, MediumInterval)), allocator);
|
||||||
out.PushBack(normalize(calc(threadId + 1, LargeInterval)), allocator);
|
out.PushBack(normalize(calc(threadId, LargeInterval)), allocator);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
double xmrig::Hashrate::hashrate(size_t index, size_t ms) const
|
||||||
|
{
|
||||||
|
assert(index < m_threads);
|
||||||
|
if (index >= m_threads) {
|
||||||
|
return nan("");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t earliestHashCount = 0;
|
||||||
|
uint64_t earliestStamp = 0;
|
||||||
|
bool haveFullSet = false;
|
||||||
|
|
||||||
|
const uint64_t timeStampLimit = xmrig::Chrono::steadyMSecs() - ms;
|
||||||
|
uint64_t* timestamps = m_timestamps[index];
|
||||||
|
uint64_t* counts = m_counts[index];
|
||||||
|
|
||||||
|
const size_t idx_start = (m_top[index] - 1) & kBucketMask;
|
||||||
|
size_t idx = idx_start;
|
||||||
|
|
||||||
|
uint64_t lastestStamp = timestamps[idx];
|
||||||
|
uint64_t lastestHashCnt = counts[idx];
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (timestamps[idx] < timeStampLimit) {
|
||||||
|
haveFullSet = (timestamps[idx] != 0);
|
||||||
|
if (idx != idx_start) {
|
||||||
|
idx = (idx + 1) & kBucketMask;
|
||||||
|
earliestStamp = timestamps[idx];
|
||||||
|
earliestHashCount = counts[idx];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
idx = (idx - 1) & kBucketMask;
|
||||||
|
} while (idx != idx_start);
|
||||||
|
|
||||||
|
if (!haveFullSet || earliestStamp == 0 || lastestStamp == 0) {
|
||||||
|
return nan("");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastestStamp - earliestStamp == 0) {
|
||||||
|
return nan("");
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto hashes = static_cast<double>(lastestHashCnt - earliestHashCount);
|
||||||
|
const auto time = static_cast<double>(lastestStamp - earliestStamp) / 1000.0;
|
||||||
|
|
||||||
|
return hashes / time;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void xmrig::Hashrate::addData(size_t index, uint64_t count, uint64_t timestamp)
|
||||||
|
{
|
||||||
|
const size_t top = m_top[index];
|
||||||
|
m_counts[index][top] = count;
|
||||||
|
m_timestamps[index][top] = timestamp;
|
||||||
|
|
||||||
|
m_top[index] = (top + 1) & kBucketMask;
|
||||||
|
}
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
/* XMRig
|
/* XMRig
|
||||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
* Copyright (c) 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -26,6 +21,7 @@
|
||||||
#define XMRIG_HASHRATE_H
|
#define XMRIG_HASHRATE_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
@ -42,7 +38,7 @@ class Hashrate
|
||||||
public:
|
public:
|
||||||
XMRIG_DISABLE_COPY_MOVE_DEFAULT(Hashrate)
|
XMRIG_DISABLE_COPY_MOVE_DEFAULT(Hashrate)
|
||||||
|
|
||||||
enum Intervals {
|
enum Intervals : size_t {
|
||||||
ShortInterval = 10000,
|
ShortInterval = 10000,
|
||||||
MediumInterval = 60000,
|
MediumInterval = 60000,
|
||||||
LargeInterval = 900000
|
LargeInterval = 900000
|
||||||
|
@ -50,11 +46,12 @@ public:
|
||||||
|
|
||||||
Hashrate(size_t threads);
|
Hashrate(size_t threads);
|
||||||
~Hashrate();
|
~Hashrate();
|
||||||
double calc(size_t ms) const;
|
|
||||||
double calc(size_t threadId, size_t ms) const;
|
|
||||||
void add(size_t threadId, uint64_t count, uint64_t timestamp);
|
|
||||||
|
|
||||||
inline size_t threads() const { return m_threads; }
|
inline double calc(size_t ms) const { const double data = hashrate(0U, ms); return std::isnormal(data) ? data : 0.0; }
|
||||||
|
inline double calc(size_t threadId, size_t ms) const { return hashrate(threadId + 1, ms); }
|
||||||
|
inline size_t threads() const { return m_threads > 0U ? m_threads - 1U : 0U; }
|
||||||
|
inline void add(size_t threadId, uint64_t count, uint64_t timestamp) { addData(threadId + 1U, count, timestamp); }
|
||||||
|
inline void add(uint64_t count, uint64_t timestamp) { addData(0U, count, timestamp); }
|
||||||
|
|
||||||
static const char *format(double h, char *buf, size_t size);
|
static const char *format(double h, char *buf, size_t size);
|
||||||
static rapidjson::Value normalize(double d);
|
static rapidjson::Value normalize(double d);
|
||||||
|
@ -65,6 +62,9 @@ public:
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
double hashrate(size_t index, size_t ms) const;
|
||||||
|
void addData(size_t index, uint64_t count, uint64_t timestamp);
|
||||||
|
|
||||||
constexpr static size_t kBucketSize = 2 << 11;
|
constexpr static size_t kBucketSize = 2 << 11;
|
||||||
constexpr static size_t kBucketMask = kBucketSize - 1;
|
constexpr static size_t kBucketMask = kBucketSize - 1;
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ bool xmrig::Workers<T>::tick(uint64_t)
|
||||||
IWorker *worker = handle->worker();
|
IWorker *worker = handle->worker();
|
||||||
if (worker) {
|
if (worker) {
|
||||||
worker->hashrateData(hashCount, ts, rawHashes);
|
worker->hashrateData(hashCount, ts, rawHashes);
|
||||||
d_ptr->hashrate->add(handle->id() + 1, hashCount, ts);
|
d_ptr->hashrate->add(handle->id(), hashCount, ts);
|
||||||
|
|
||||||
if (rawHashes == 0) {
|
if (rawHashes == 0) {
|
||||||
totalAvailable = false;
|
totalAvailable = false;
|
||||||
|
@ -104,7 +104,7 @@ bool xmrig::Workers<T>::tick(uint64_t)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (totalAvailable) {
|
if (totalAvailable) {
|
||||||
d_ptr->hashrate->add(0, totalHashCount, Chrono::steadyMSecs());
|
d_ptr->hashrate->add(totalHashCount, Chrono::steadyMSecs());
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifdef XMRIG_FEATURE_BENCHMARK
|
# ifdef XMRIG_FEATURE_BENCHMARK
|
||||||
|
|
|
@ -322,9 +322,9 @@ void xmrig::CpuBackend::printHashrate(bool details)
|
||||||
Log::print("| %8zu | %8" PRId64 " | %7s | %7s | %7s |",
|
Log::print("| %8zu | %8" PRId64 " | %7s | %7s | %7s |",
|
||||||
i,
|
i,
|
||||||
data.affinity,
|
data.affinity,
|
||||||
Hashrate::format(hashrate()->calc(i + 1, Hashrate::ShortInterval), num, sizeof num / 3),
|
Hashrate::format(hashrate()->calc(i, Hashrate::ShortInterval), num, sizeof num / 3),
|
||||||
Hashrate::format(hashrate()->calc(i + 1, Hashrate::MediumInterval), num + 8, sizeof num / 3),
|
Hashrate::format(hashrate()->calc(i, Hashrate::MediumInterval), num + 8, sizeof num / 3),
|
||||||
Hashrate::format(hashrate()->calc(i + 1, Hashrate::LargeInterval), num + 8 * 2, sizeof num / 3)
|
Hashrate::format(hashrate()->calc(i, Hashrate::LargeInterval), num + 8 * 2, sizeof num / 3)
|
||||||
);
|
);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
|
@ -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"),
|
Log::print("| %8zu | %8" PRId64 " | %8s | %8s | %8s |" CYAN_BOLD(" #%u") YELLOW(" %s") GREEN(" %s"),
|
||||||
i,
|
i,
|
||||||
data.thread.affinity(),
|
data.thread.affinity(),
|
||||||
Hashrate::format(hashrate()->calc(i + 1, Hashrate::ShortInterval) * scale, num, sizeof num / 3),
|
Hashrate::format(hashrate()->calc(i, 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, Hashrate::MediumInterval) * scale, num + 16, sizeof num / 3),
|
||||||
Hashrate::format(hashrate()->calc(i + 1, Hashrate::LargeInterval) * scale, num + 16 * 2, sizeof num / 3),
|
Hashrate::format(hashrate()->calc(i, Hashrate::LargeInterval) * scale, num + 16 * 2, sizeof num / 3),
|
||||||
data.device.index(),
|
data.device.index(),
|
||||||
data.device.topology().toString().data(),
|
data.device.topology().toString().data(),
|
||||||
data.device.name().data()
|
data.device.name().data()
|
||||||
|
|
|
@ -385,9 +385,9 @@ void xmrig::OclBackend::printHashrate(bool details)
|
||||||
Log::print("| %8zu | %8" PRId64 " | %8s | %8s | %8s |" CYAN_BOLD(" #%u") YELLOW(" %s") " %s",
|
Log::print("| %8zu | %8" PRId64 " | %8s | %8s | %8s |" CYAN_BOLD(" #%u") YELLOW(" %s") " %s",
|
||||||
i,
|
i,
|
||||||
data.affinity,
|
data.affinity,
|
||||||
Hashrate::format(hashrate()->calc(i + 1, Hashrate::ShortInterval) * scale, num, sizeof num / 3),
|
Hashrate::format(hashrate()->calc(i, 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, Hashrate::MediumInterval) * scale, num + 16, sizeof num / 3),
|
||||||
Hashrate::format(hashrate()->calc(i + 1, Hashrate::LargeInterval) * scale, num + 16 * 2, sizeof num / 3),
|
Hashrate::format(hashrate()->calc(i, Hashrate::LargeInterval) * scale, num + 16 * 2, sizeof num / 3),
|
||||||
data.device.index(),
|
data.device.index(),
|
||||||
data.device.topology().toString().data(),
|
data.device.topology().toString().data(),
|
||||||
data.device.printableName().data()
|
data.device.printableName().data()
|
||||||
|
|
|
@ -203,7 +203,7 @@ public:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 1; i < hr->threads(); i++) {
|
for (size_t i = 0; i < hr->threads(); i++) {
|
||||||
Value thread(kArrayType);
|
Value thread(kArrayType);
|
||||||
thread.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::ShortInterval)), allocator);
|
thread.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::ShortInterval)), allocator);
|
||||||
thread.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::MediumInterval)), allocator);
|
thread.PushBack(Hashrate::normalize(hr->calc(i, Hashrate::MediumInterval)), allocator);
|
||||||
|
|
Loading…
Reference in a new issue