Add class Telemetry.
This commit is contained in:
parent
6774f86fcd
commit
a370b8fd30
11 changed files with 241 additions and 5 deletions
|
@ -21,6 +21,7 @@ set(HEADERS
|
|||
src/Summary.h
|
||||
src/workers/Handle.h
|
||||
src/workers/SingleWorker.h
|
||||
src/workers/Telemetry.h
|
||||
src/workers/Worker.h
|
||||
src/workers/Workers.h
|
||||
src/version.h
|
||||
|
@ -52,6 +53,7 @@ set(SOURCES
|
|||
src/Summary.cpp
|
||||
src/workers/Handle.cpp
|
||||
src/workers/SingleWorker.cpp
|
||||
src/workers/Telemetry.cpp
|
||||
src/workers/Worker.cpp
|
||||
src/workers/Workers.cpp
|
||||
src/xmrig.cpp
|
||||
|
@ -86,7 +88,7 @@ endif()
|
|||
|
||||
add_definitions(/D_GNU_SOURCE)
|
||||
add_definitions(/DUNICODE)
|
||||
add_definitions(/DAPP_DEBUG)
|
||||
#add_definitions(/DAPP_DEBUG)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
|
||||
|
||||
|
|
|
@ -34,10 +34,10 @@ class IClientListener
|
|||
public:
|
||||
virtual ~IClientListener() {}
|
||||
|
||||
virtual void onClose(Client *client, int failures);
|
||||
virtual void onClose(Client *client, int failures) = 0;
|
||||
virtual void onJobReceived(Client *client, const Job &job) = 0;
|
||||
virtual void onLoginCredentialsRequired(Client *client) = 0;
|
||||
virtual void onLoginSuccess(Client *client) = 0;
|
||||
virtual void onLoginCredentialsRequired(Client *client) = 0;
|
||||
virtual void onLoginSuccess(Client *client) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -25,12 +25,17 @@
|
|||
#define __IWORKER_H__
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
class IWorker
|
||||
{
|
||||
public:
|
||||
virtual ~IWorker() {}
|
||||
|
||||
virtual void start() = 0;
|
||||
virtual uint64_t hashCount() const = 0;
|
||||
virtual uint64_t timestamp() const = 0;
|
||||
virtual void start() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ public:
|
|||
inline int threadId() const { return m_threadId; }
|
||||
inline int threads() const { return m_threads; }
|
||||
inline int64_t affinity() const { return m_affinity; }
|
||||
inline IWorker *worker() const { return m_worker; }
|
||||
inline void setWorker(IWorker *worker) { m_worker = worker; }
|
||||
|
||||
private:
|
||||
|
|
|
@ -51,6 +51,10 @@ void SingleWorker::start()
|
|||
}
|
||||
|
||||
while (!Workers::isOutdated(m_sequence)) {
|
||||
if ((m_count & 0xF) == 0) {
|
||||
storeStats();
|
||||
}
|
||||
|
||||
m_count++;
|
||||
*m_job.nonce() = ++m_result.nonce;
|
||||
|
||||
|
|
107
src/workers/Telemetry.cpp
Normal file
107
src/workers/Telemetry.cpp
Normal file
|
@ -0,0 +1,107 @@
|
|||
/* 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 2016-2017 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 <memory.h>
|
||||
#include <math.h>
|
||||
#include <chrono>
|
||||
|
||||
#include "Console.h"
|
||||
#include "workers/Telemetry.h"
|
||||
|
||||
|
||||
Telemetry::Telemetry(int threads) :
|
||||
m_threads(threads)
|
||||
{
|
||||
m_counts = new uint64_t*[threads];
|
||||
m_timestamps = new uint64_t*[threads];
|
||||
m_top = new uint32_t[threads];
|
||||
|
||||
for (int i = 0; i < threads; i++) {
|
||||
m_counts[i] = new uint64_t[kBucketSize];
|
||||
m_timestamps[i] = new uint64_t[kBucketSize];
|
||||
m_top[i] = 0;
|
||||
|
||||
memset(m_counts[0], 0, sizeof(uint64_t) * kBucketSize);
|
||||
memset(m_timestamps[0], 0, sizeof(uint64_t) * kBucketSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double Telemetry::calc(size_t threadId, size_t ms) const
|
||||
{
|
||||
using namespace std::chrono;
|
||||
const uint64_t now = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();
|
||||
|
||||
uint64_t earliestHashCount = 0;
|
||||
uint64_t earliestStamp = 0;
|
||||
uint64_t lastestStamp = 0;
|
||||
uint64_t lastestHashCnt = 0;
|
||||
bool haveFullSet = false;
|
||||
|
||||
for (size_t i = 1; i < kBucketSize; i++) {
|
||||
const size_t idx = (m_top[threadId] - i) & kBucketMask;
|
||||
|
||||
if (m_timestamps[threadId][idx] == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (lastestStamp == 0) {
|
||||
lastestStamp = m_timestamps[threadId][idx];
|
||||
lastestHashCnt = m_counts[threadId][idx];
|
||||
}
|
||||
|
||||
if (now - m_timestamps[threadId][idx] > ms) {
|
||||
haveFullSet = true;
|
||||
break;
|
||||
}
|
||||
|
||||
earliestStamp = m_timestamps[threadId][idx];
|
||||
earliestHashCount = m_counts[threadId][idx];
|
||||
}
|
||||
|
||||
if (!haveFullSet || earliestStamp == 0 || lastestStamp == 0) {
|
||||
return nan("");
|
||||
}
|
||||
|
||||
if (lastestStamp - earliestStamp == 0) {
|
||||
return nan("");
|
||||
}
|
||||
|
||||
double hashes, time;
|
||||
hashes = lastestHashCnt - earliestHashCount;
|
||||
time = lastestStamp - earliestStamp;
|
||||
time /= 1000.0;
|
||||
|
||||
return hashes / time;
|
||||
}
|
||||
|
||||
|
||||
void Telemetry::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;
|
||||
}
|
49
src/workers/Telemetry.h
Normal file
49
src/workers/Telemetry.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* 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 2016-2017 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 __TELEMETRY_H__
|
||||
#define __TELEMETRY_H__
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
class Telemetry
|
||||
{
|
||||
public:
|
||||
Telemetry(int threads);
|
||||
double calc(size_t threadId, size_t ms) const;
|
||||
void add(size_t threadId, uint64_t count, uint64_t timestamp);
|
||||
|
||||
private:
|
||||
constexpr static size_t kBucketSize = 2 << 11;
|
||||
constexpr static size_t kBucketMask = kBucketSize - 1;
|
||||
|
||||
int m_threads;
|
||||
uint32_t* m_top;
|
||||
uint64_t** m_counts;
|
||||
uint64_t** m_timestamps;
|
||||
};
|
||||
|
||||
|
||||
#endif /* __TELEMETRY_H__ */
|
|
@ -21,6 +21,9 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "Console.h"
|
||||
|
||||
#include "Cpu.h"
|
||||
#include "Mem.h"
|
||||
|
@ -32,6 +35,8 @@ Worker::Worker(Handle *handle) :
|
|||
m_nicehash(handle->nicehash()),
|
||||
m_id(handle->threadId()),
|
||||
m_threads(handle->threads()),
|
||||
m_hashCount(0),
|
||||
m_timestamp(0),
|
||||
m_count(0),
|
||||
m_sequence(0)
|
||||
{
|
||||
|
@ -48,3 +53,13 @@ Worker::Worker(Handle *handle) :
|
|||
Worker::~Worker()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Worker::storeStats()
|
||||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
const uint64_t timestamp = time_point_cast<milliseconds>(high_resolution_clock::now()).time_since_epoch().count();
|
||||
m_hashCount.store(m_count, std::memory_order_relaxed);
|
||||
m_timestamp.store(timestamp, std::memory_order_relaxed);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#define __WORKER_H__
|
||||
|
||||
|
||||
#include <atomic>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
@ -41,11 +42,18 @@ public:
|
|||
Worker(Handle *handle);
|
||||
~Worker();
|
||||
|
||||
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); }
|
||||
|
||||
protected:
|
||||
void storeStats();
|
||||
|
||||
bool m_nicehash;
|
||||
cryptonight_ctx *m_ctx;
|
||||
int m_id;
|
||||
int m_threads;
|
||||
std::atomic<uint64_t> m_hashCount;
|
||||
std::atomic<uint64_t> m_timestamp;
|
||||
uint64_t m_count;
|
||||
uint64_t m_sequence;
|
||||
};
|
||||
|
|
|
@ -21,9 +21,14 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
|
||||
|
||||
#include "Console.h"
|
||||
#include "interfaces/IJobResultListener.h"
|
||||
#include "workers/Handle.h"
|
||||
#include "workers/SingleWorker.h"
|
||||
#include "workers/Telemetry.h"
|
||||
#include "workers/Workers.h"
|
||||
|
||||
|
||||
|
@ -35,7 +40,10 @@ std::atomic<int> Workers::m_paused;
|
|||
std::atomic<uint64_t> Workers::m_sequence;
|
||||
std::list<JobResult> Workers::m_queue;
|
||||
std::vector<Handle*> Workers::m_workers;
|
||||
Telemetry *Workers::m_telemetry = nullptr;
|
||||
uint64_t Workers::m_ticks = 0;
|
||||
uv_async_t Workers::m_async;
|
||||
uv_timer_t Workers::m_timer;
|
||||
|
||||
|
||||
Job Workers::job()
|
||||
|
@ -61,6 +69,8 @@ void Workers::setJob(const Job &job)
|
|||
|
||||
void Workers::start(int threads, int64_t affinity, bool nicehash)
|
||||
{
|
||||
m_telemetry = new Telemetry(threads);
|
||||
|
||||
pthread_mutex_init(&m_mutex, nullptr);
|
||||
pthread_rwlock_init(&m_rwlock, nullptr);
|
||||
|
||||
|
@ -68,6 +78,8 @@ void Workers::start(int threads, int64_t affinity, bool nicehash)
|
|||
m_paused = 1;
|
||||
|
||||
uv_async_init(uv_default_loop(), &m_async, Workers::onResult);
|
||||
uv_timer_init(uv_default_loop(), &m_timer);
|
||||
uv_timer_start(&m_timer, Workers::onPerfTick, 500, 500);
|
||||
|
||||
for (int i = 0; i < threads; ++i) {
|
||||
Handle *handle = new Handle(i, threads, affinity, nicehash);
|
||||
|
@ -98,6 +110,34 @@ void *Workers::onReady(void *arg)
|
|||
}
|
||||
|
||||
|
||||
void Workers::onPerfTick(uv_timer_t *handle)
|
||||
{
|
||||
for (Handle *handle : m_workers) {
|
||||
m_telemetry->add(handle->threadId(), handle->worker()->hashCount(), handle->worker()->timestamp());
|
||||
}
|
||||
|
||||
if ((m_ticks++ & 0xF) == 0) {
|
||||
double hps = 0.0;
|
||||
double telem;
|
||||
bool normal = true;
|
||||
|
||||
for (Handle *handle : m_workers) {
|
||||
telem = m_telemetry->calc(handle->threadId(), 2500);
|
||||
if (!std::isnormal(telem)) {
|
||||
normal = false;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
hps += telem;
|
||||
}
|
||||
}
|
||||
|
||||
if (normal) {
|
||||
LOG_NOTICE("%03.1f H/s", hps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Workers::onResult(uv_async_t *handle)
|
||||
{
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
class Handle;
|
||||
class IJobResultListener;
|
||||
class Telemetry;
|
||||
|
||||
|
||||
class Workers
|
||||
|
@ -55,6 +56,7 @@ public:
|
|||
|
||||
private:
|
||||
static void *onReady(void *arg);
|
||||
static void onPerfTick(uv_timer_t *handle);
|
||||
static void onResult(uv_async_t *handle);
|
||||
|
||||
static IJobResultListener *m_listener;
|
||||
|
@ -65,7 +67,10 @@ private:
|
|||
static std::atomic<uint64_t> m_sequence;
|
||||
static std::list<JobResult> m_queue;
|
||||
static std::vector<Handle*> m_workers;
|
||||
static Telemetry *m_telemetry;
|
||||
static uint64_t m_ticks;
|
||||
static uv_async_t m_async;
|
||||
static uv_timer_t m_timer;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue