Added support for threads restart if config changed.

This commit is contained in:
XMRig 2019-07-18 19:11:45 +07:00
parent 871bc3e180
commit f590cf58fb
12 changed files with 105 additions and 62 deletions

View file

@ -78,13 +78,6 @@ const xmrig::Hashrate *xmrig::Workers<T>::hashrate() const
}
template<class T>
void xmrig::Workers<T>::add(const T &data)
{
m_workers.push_back(new Thread<T>(d_ptr->backend, m_workers.size(), data));
}
template<class T>
void xmrig::Workers<T>::setBackend(IBackend *backend)
{
@ -93,8 +86,12 @@ void xmrig::Workers<T>::setBackend(IBackend *backend)
template<class T>
void xmrig::Workers<T>::start()
void xmrig::Workers<T>::start(const std::vector<T> &data)
{
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());
for (Thread<T> *worker : m_workers) {

View file

@ -46,9 +46,8 @@ public:
~Workers();
const Hashrate *hashrate() const;
void add(const T &data);
void setBackend(IBackend *backend);
void start();
void start(const std::vector<T> &data);
void stop();
void tick(uint64_t ticks);

View file

@ -32,6 +32,7 @@
namespace xmrig {
class Algorithm;
class Hashrate;
class IWorker;
class Job;
@ -43,13 +44,14 @@ class IBackend
public:
virtual ~IBackend() = default;
virtual const Hashrate *hashrate() const = 0;
virtual const String &profileName() const = 0;
virtual void printHashrate(bool details) = 0;
virtual void setJob(const Job &job) = 0;
virtual void start(IWorker *worker) = 0;
virtual void stop() = 0;
virtual void tick(uint64_t ticks) = 0;
virtual bool isEnabled(const Algorithm &algorithm) const = 0;
virtual const Hashrate *hashrate() const = 0;
virtual const String &profileName() const = 0;
virtual void printHashrate(bool details) = 0;
virtual void setJob(const Job &job) = 0;
virtual void start(IWorker *worker) = 0;
virtual void stop() = 0;
virtual void tick(uint64_t ticks) = 0;
};

View file

@ -85,40 +85,8 @@ public:
}
inline bool isReady(const Algorithm &nextAlgo) const
inline void start()
{
if (!algo.isValid()) {
return false;
}
if (nextAlgo == algo) {
return true;
}
const CpuThreads &nextThreads = controller->config()->cpu().threads().get(nextAlgo);
return algo.memory() == nextAlgo.memory()
&& threads.size() == nextThreads.size()
&& std::equal(threads.begin(), threads.end(), nextThreads.begin());
}
inline void start(const Job &job)
{
const CpuConfig &cpu = controller->config()->cpu();
algo = job.algorithm();
profileName = cpu.threads().profileName(job.algorithm());
threads = cpu.threads().get(profileName);
if (profileName.isNull() || threads.empty()) {
workers.stop();
LOG_WARN(YELLOW_BOLD_S "CPU disabled, no suitable configuration for algo %s", job.algorithm().shortName());
return;
}
LOG_INFO(GREEN_BOLD("CPU") " use profile " BLUE_BG(WHITE_BOLD_S " %s ") WHITE_BOLD_S " (" CYAN_BOLD("%zu") WHITE_BOLD(" threads)") " scratchpad " CYAN_BOLD("%zu KB"),
profileName.data(),
threads.size(),
@ -131,20 +99,18 @@ public:
status.memory = algo.memory();
status.threads = threads.size();
for (const CpuThread &thread : threads) {
workers.add(CpuLaunchData(controller->miner(), algo, cpu, thread));
status.ways += static_cast<size_t>(thread.intensity());
for (const CpuLaunchData &data : threads) {
status.ways += static_cast<size_t>(data.intensity);
}
workers.start();
workers.start(threads);
}
Algorithm algo;
Controller *controller;
CpuThreads threads;
LaunchStatus status;
std::vector<CpuLaunchData> threads;
String profileName;
uv_mutex_t mutex;
Workers<CpuLaunchData> workers;
@ -167,6 +133,12 @@ xmrig::CpuBackend::~CpuBackend()
}
bool xmrig::CpuBackend::isEnabled(const Algorithm &algorithm) const
{
return !d_ptr->controller->config()->cpu().threads().get(algorithm).empty();
}
const xmrig::Hashrate *xmrig::CpuBackend::hashrate() const
{
return d_ptr->workers.hashrate();
@ -190,10 +162,10 @@ void xmrig::CpuBackend::printHashrate(bool details)
Log::print(WHITE_BOLD_S "| CPU THREAD | AFFINITY | 10s H/s | 60s H/s | 15m H/s |");
size_t i = 0;
for (const CpuThread &thread : d_ptr->threads) {
for (const CpuLaunchData &data : d_ptr->threads) {
Log::print("| %13zu | %8" PRId64 " | %7s | %7s | %7s |",
i,
thread.affinity(),
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)
@ -206,11 +178,26 @@ void xmrig::CpuBackend::printHashrate(bool details)
void xmrig::CpuBackend::setJob(const Job &job)
{
if (d_ptr->isReady(job.algorithm())) {
const CpuConfig &cpu = d_ptr->controller->config()->cpu();
std::vector<CpuLaunchData> threads = cpu.get(d_ptr->controller->miner(), job.algorithm());
if (d_ptr->threads.size() == threads.size() && std::equal(d_ptr->threads.begin(), d_ptr->threads.end(), threads.begin())) {
return;
}
d_ptr->start(job);
d_ptr->algo = job.algorithm();
d_ptr->profileName = cpu.threads().profileName(job.algorithm());
if (d_ptr->profileName.isNull() || threads.empty()) {
d_ptr->workers.stop();
LOG_WARN(YELLOW_BOLD_S "CPU disabled, no suitable configuration for algo %s", job.algorithm().shortName());
return;
}
d_ptr->threads = std::move(threads);
d_ptr->start();
}

View file

@ -44,6 +44,7 @@ public:
~CpuBackend() override;
protected:
bool isEnabled(const Algorithm &algorithm) const override;
const Hashrate *hashrate() const override;
const String &profileName() const override;
void printHashrate(bool details) override;

View file

@ -100,6 +100,25 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const
}
std::vector<xmrig::CpuLaunchData> xmrig::CpuConfig::get(const Miner *miner, const Algorithm &algorithm) const
{
std::vector<CpuLaunchData> out;
const std::vector<CpuThread> &threads = m_threads.get(algorithm);
if (threads.empty()) {
return out;
}
out.reserve(threads.size());
for (const CpuThread &thread : threads) {
out.push_back(CpuLaunchData(miner, algorithm, *this, thread));
}
return out;
}
void xmrig::CpuConfig::read(const rapidjson::Value &value)
{
if (value.IsObject()) {

View file

@ -27,6 +27,7 @@
#include "backend/common/Threads.h"
#include "backend/cpu/CpuLaunchData.h"
#include "backend/cpu/CpuThread.h"
#include "crypto/common/Assembly.h"
@ -47,6 +48,7 @@ public:
bool isHwAES() const;
rapidjson::Value toJSON(rapidjson::Document &doc) const;
std::vector<CpuLaunchData> get(const Miner *miner, const Algorithm &algorithm) const;
void read(const rapidjson::Value &value);
inline bool isEnabled() const { return m_enabled; }

View file

@ -41,6 +41,19 @@ xmrig::CpuLaunchData::CpuLaunchData(const Miner *miner, const Algorithm &algorit
}
bool xmrig::CpuLaunchData::isEqual(const CpuLaunchData &other) const
{
return (algorithm.memory() == other.algorithm.memory()
&& assembly == other.assembly
&& hugePages == other.hugePages
&& hwAES == other.hwAES
&& intensity == other.intensity
&& priority == other.priority
&& affinity == other.affinity
);
}
xmrig::CnHash::AlgoVariant xmrig::CpuLaunchData::av() const
{
if (intensity <= 2) {

View file

@ -46,10 +46,14 @@ class CpuLaunchData
public:
CpuLaunchData(const Miner *miner, const Algorithm &algorithm, const CpuConfig &config, const CpuThread &thread);
bool isEqual(const CpuLaunchData &other) const;
CnHash::AlgoVariant av() const;
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); }
const Algorithm algorithm;
const Assembly assembly;
const bool hugePages;

View file

@ -192,7 +192,8 @@ bool xmrig::Pool::isEqual(const Pool &other) const
&& m_rigId == other.m_rigId
&& m_url == other.m_url
&& m_user == other.m_user
&& m_pollInterval == other.m_pollInterval);
&& m_pollInterval == other.m_pollInterval
);
}

View file

@ -99,6 +99,8 @@ public:
xmrig::Miner::Miner(Controller *controller)
: d_ptr(new MinerPrivate(controller))
{
controller->addListener(this);
d_ptr->timer = new Timer(this);
d_ptr->backends.push_back(new CpuBackend(controller));
@ -218,6 +220,20 @@ void xmrig::Miner::stop()
}
void xmrig::Miner::onConfigChanged(Config *config, Config *previousConfig)
{
if (config->pools() != previousConfig->pools() && config->pools().active() > 0) {
return;
}
const Job job = this->job();
for (IBackend *backend : d_ptr->backends) {
backend->setJob(job);
}
}
void xmrig::Miner::onTimer(const Timer *)
{
double maxHashrate = 0.0;

View file

@ -29,6 +29,7 @@
#include <vector>
#include "base/kernel/interfaces/IBaseListener.h"
#include "base/kernel/interfaces/ITimerListener.h"
@ -41,7 +42,7 @@ class MinerPrivate;
class IBackend;
class Miner : public ITimerListener
class Miner : public ITimerListener, public IBaseListener
{
public:
Miner(Controller *controller);
@ -57,6 +58,7 @@ public:
void stop();
protected:
void onConfigChanged(Config *config, Config *previousConfig) override;
void onTimer(const Timer *timer) override;
private: