Added support for extended threads and algo-perf config parameters

This commit is contained in:
MoneroOcean 2018-07-18 16:40:38 +02:00
parent 5f73919be1
commit a8d399e450
3 changed files with 131 additions and 52 deletions

View file

@ -6,6 +6,7 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018 MoneroOcean <https://github.com/MoneroOcean>, <support@moneroocean.stream>
* *
* 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
@ -36,6 +37,10 @@
#include "rapidjson/prettywriter.h" #include "rapidjson/prettywriter.h"
#include "workers/CpuThread.h" #include "workers/CpuThread.h"
// for usage in Client::login to get_algo_perf
namespace xmrig {
Config* pconfig = nullptr;
};
static char affinity_tmp[20] = { 0 }; static char affinity_tmp[20] = { 0 };
@ -48,6 +53,11 @@ xmrig::Config::Config() : xmrig::CommonConfig(),
m_maxCpuUsage(75), m_maxCpuUsage(75),
m_priority(-1) m_priority(-1)
{ {
// not defined algo performance is considered to be 0
for (int a = 0; a != xmrig::PerfAlgo::PA_MAX; ++ a) {
const xmrig::PerfAlgo pa = static_cast<xmrig::PerfAlgo>(a);
m_algo_perf[pa] = 0;
}
} }
@ -111,18 +121,34 @@ void xmrig::Config::getJSON(rapidjson::Document &doc) const
doc.AddMember("retry-pause", retryPause(), allocator); doc.AddMember("retry-pause", retryPause(), allocator);
doc.AddMember("safe", m_safe, allocator); doc.AddMember("safe", m_safe, allocator);
if (threadsMode() == Advanced) { // save extended "threads" based on m_threads
Value threads(kArrayType); Value threads(kObjectType);
for (int a = 0; a != xmrig::PerfAlgo::PA_MAX; ++ a) {
const xmrig::PerfAlgo pa = static_cast<xmrig::PerfAlgo>(a);
Value key(xmrig::Algorithm::perfAlgoName(pa), allocator);
if (threadsMode(pa) == Advanced) {
Value threads2(kArrayType);
for (const IThread *thread : m_threads.list) { for (const IThread *thread : m_threads[pa].list) {
threads.PushBack(thread->toConfig(doc), allocator); threads2.PushBack(thread->toConfig(doc), allocator);
} }
doc.AddMember("threads", threads, allocator); threads.AddMember(key, threads2, allocator);
} }
else { else {
doc.AddMember("threads", threadsMode() == Automatic ? Value(kNullType) : Value(threadsCount()), allocator); threads.AddMember(key, threadsMode(pa) == Automatic ? Value(kNullType) : Value(threadsCount(pa)), allocator);
} }
}
doc.AddMember("threads", threads, allocator);
// save "algo-perf" based on m_algo_perf
Value algo_perf(kObjectType);
for (int a = 0; a != xmrig::PerfAlgo::PA_MAX; ++ a) {
const xmrig::PerfAlgo pa = static_cast<xmrig::PerfAlgo>(a);
Value key(xmrig::Algorithm::perfAlgoName(pa), allocator);
algo_perf.AddMember(key, Value(m_algo_perf[pa]), allocator);
}
doc.AddMember("algo-perf", algo_perf, allocator);
doc.AddMember("user-agent", userAgent() ? Value(StringRef(userAgent())).Move() : Value(kNullType).Move(), allocator); doc.AddMember("user-agent", userAgent() ? Value(StringRef(userAgent())).Move() : Value(kNullType).Move(), allocator);
@ -150,34 +176,36 @@ bool xmrig::Config::finalize()
return false; return false;
} }
if (!m_threads.cpu.empty()) { // parse "threads" into m_threads
m_threads.mode = Advanced; for (int a = 0; a != xmrig::PerfAlgo::PA_MAX; ++ a) {
const xmrig::PerfAlgo pa = static_cast<xmrig::PerfAlgo>(a);
if (!m_threads[pa].cpu.empty()) {
m_threads[pa].mode = Advanced;
const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT; const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT;
for (size_t i = 0; i < m_threads.cpu.size(); ++i) { for (size_t i = 0; i < m_threads[pa].cpu.size(); ++i) {
m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm.algo(), m_threads.cpu[i], m_priority, softAES)); m_threads[pa].list.push_back(CpuThread::createFromData(i, xmrig::Algorithm(pa).algo(), m_threads[pa].cpu[i], m_priority, softAES));
} }
} else {
return true;
}
const AlgoVariant av = getAlgoVariant(); const AlgoVariant av = getAlgoVariant();
m_threads.mode = m_threads.count ? Simple : Automatic; m_threads[pa].mode = m_threads[pa].count ? Simple : Automatic;
const size_t size = CpuThread::multiway(av) * cn_select_memory(m_algorithm.algo()) / 1024; const size_t size = CpuThread::multiway(av) * cn_select_memory(xmrig::Algorithm(pa).algo()) / 1024;
if (!m_threads.count) { if (!m_threads[pa].count) {
m_threads.count = Cpu::optimalThreadsCount(size, m_maxCpuUsage); m_threads[pa].count = Cpu::optimalThreadsCount(size, m_maxCpuUsage);
} }
else if (m_safe) { else if (m_safe) {
const size_t count = Cpu::optimalThreadsCount(size, m_maxCpuUsage); const size_t count = Cpu::optimalThreadsCount(size, m_maxCpuUsage);
if (m_threads.count > count) { if (m_threads[pa].count > count) {
m_threads.count = count; m_threads[pa].count = count;
} }
} }
for (size_t i = 0; i < m_threads.count; ++i) { for (size_t i = 0; i < m_threads[pa].count; ++i) {
m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm.algo(), av, m_threads.mask, m_priority)); m_threads[pa].list.push_back(CpuThread::createFromAV(i, xmrig::Algorithm(pa).algo(), av, m_threads[pa].mask, m_priority));
}
}
} }
return true; return true;
@ -231,7 +259,7 @@ bool xmrig::Config::parseString(int key, const char *arg)
case ThreadsKey: /* --threads */ case ThreadsKey: /* --threads */
if (strncmp(arg, "all", 3) == 0) { if (strncmp(arg, "all", 3) == 0) {
m_threads.count = Cpu::threads(); m_threads[m_algorithm.perf_algo()].count = Cpu::threads(); // sets default algo threads
return true; return true;
} }
@ -260,7 +288,7 @@ bool xmrig::Config::parseUint64(int key, uint64_t arg)
switch (key) { switch (key) {
case CPUAffinityKey: /* --cpu-affinity */ case CPUAffinityKey: /* --cpu-affinity */
if (arg) { if (arg) {
m_threads.mask = arg; m_threads[m_algorithm.perf_algo()].mask = arg; // sets default algo threads
} }
break; break;
@ -272,11 +300,9 @@ bool xmrig::Config::parseUint64(int key, uint64_t arg)
} }
void xmrig::Config::parseJSON(const rapidjson::Document &doc) // parse specific perf algo (or generic) threads config
void xmrig::Config::parseThreadsJSON(const rapidjson::Value &threads, const xmrig::PerfAlgo pa)
{ {
const rapidjson::Value &threads = doc["threads"];
if (threads.IsArray()) {
for (const rapidjson::Value &value : threads.GetArray()) { for (const rapidjson::Value &value : threads.GetArray()) {
if (!value.IsObject()) { if (!value.IsObject()) {
continue; continue;
@ -286,10 +312,39 @@ void xmrig::Config::parseJSON(const rapidjson::Document &doc)
auto data = CpuThread::parse(value); auto data = CpuThread::parse(value);
if (data.valid) { if (data.valid) {
m_threads.cpu.push_back(std::move(data)); m_threads[pa].cpu.push_back(std::move(data));
} }
} }
} }
}
void xmrig::Config::parseJSON(const rapidjson::Document &doc)
{
const rapidjson::Value &threads = doc["threads"];
if (threads.IsArray()) {
// parse generic (old) threads
parseThreadsJSON(threads, m_algorithm.perf_algo());
} else if (threads.IsObject()) {
// parse new specific perf algo threads
for (int a = 0; a != xmrig::PerfAlgo::PA_MAX; ++ a) {
const xmrig::PerfAlgo pa = static_cast<xmrig::PerfAlgo>(a);
const rapidjson::Value &threads2 = threads[xmrig::Algorithm::perfAlgoName(pa)];
if (threads2.IsArray()) {
parseThreadsJSON(threads2, pa);
}
}
}
const rapidjson::Value &algo_perf = doc["algo-perf"];
if (algo_perf.IsObject()) {
for (int a = 0; a != xmrig::PerfAlgo::PA_MAX; ++ a) {
const xmrig::PerfAlgo pa = static_cast<xmrig::PerfAlgo>(a);
const rapidjson::Value &key = algo_perf[xmrig::Algorithm::perfAlgoName(pa)];
if (key.IsDouble()) {
m_algo_perf[pa] = key.GetDouble();
}
}
} }
} }
@ -299,7 +354,7 @@ bool xmrig::Config::parseInt(int key, int arg)
switch (key) { switch (key) {
case ThreadsKey: /* --threads */ case ThreadsKey: /* --threads */
if (arg >= 0 && arg < 1024) { if (arg >= 0 && arg < 1024) {
m_threads.count = arg; m_threads[m_algorithm.perf_algo()].count = arg; // sets default algo threads
} }
break; break;

View file

@ -6,6 +6,7 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018 MoneroOcean <https://github.com/MoneroOcean>, <support@moneroocean.stream>
* *
* 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
@ -78,11 +79,25 @@ public:
inline AesMode aesMode() const { return m_aesMode; } inline AesMode aesMode() const { return m_aesMode; }
inline AlgoVariant algoVariant() const { return m_algoVariant; } inline AlgoVariant algoVariant() const { return m_algoVariant; }
inline bool isHugePages() const { return m_hugePages; } inline bool isHugePages() const { return m_hugePages; }
inline const std::vector<IThread *> &threads() const { return m_threads.list; }
inline int priority() const { return m_priority; } inline int priority() const { return m_priority; }
inline int threadsCount() const { return m_threads.list.size(); }
inline int64_t affinity() const { return m_threads.mask; } // access to m_threads taking into accoun that it is now separated for each perf algo
inline ThreadsMode threadsMode() const { return m_threads.mode; } inline const std::vector<IThread *> &threads(const xmrig::PerfAlgo pa = PA_INVALID) const {
return m_threads[pa == PA_INVALID ? m_algorithm.perf_algo() : pa].list;
}
inline int threadsCount(const xmrig::PerfAlgo pa = PA_INVALID) const {
return m_threads[pa == PA_INVALID ? m_algorithm.perf_algo() : pa].list.size();
}
inline int64_t affinity(const xmrig::PerfAlgo pa = PA_INVALID) const {
return m_threads[pa == PA_INVALID ? m_algorithm.perf_algo() : pa].mask;
}
inline ThreadsMode threadsMode(const xmrig::PerfAlgo pa = PA_INVALID) const {
return m_threads[pa == PA_INVALID ? m_algorithm.perf_algo() : pa].mode;
}
// access to perf algo results
inline float get_algo_perf(const xmrig::PerfAlgo pa) const { return m_algo_perf[pa]; }
inline void set_algo_perf(const xmrig::PerfAlgo pa, const float value) { m_algo_perf[pa] = value; }
static Config *load(int argc, char **argv, IWatcherListener *listener); static Config *load(int argc, char **argv, IWatcherListener *listener);
@ -92,6 +107,8 @@ protected:
bool parseString(int key, const char *arg) override; bool parseString(int key, const char *arg) override;
bool parseUint64(int key, uint64_t arg) override; bool parseUint64(int key, uint64_t arg) override;
void parseJSON(const rapidjson::Document &doc) override; void parseJSON(const rapidjson::Document &doc) override;
// parse specific perf algo (or generic) threads config
void parseThreadsJSON(const rapidjson::Value &threads, xmrig::PerfAlgo);
private: private:
bool parseInt(int key, int arg); bool parseInt(int key, int arg);
@ -120,9 +137,14 @@ private:
bool m_safe; bool m_safe;
int m_maxCpuUsage; int m_maxCpuUsage;
int m_priority; int m_priority;
Threads m_threads; // threads config for each perf algo
Threads m_threads[xmrig::PerfAlgo::PA_MAX];
// perf algo hashrate results
float m_algo_perf[xmrig::PerfAlgo::PA_MAX];
}; };
extern Config* pconfig;
} /* namespace xmrig */ } /* namespace xmrig */

View file

@ -6,6 +6,7 @@
* Copyright 2016 Jay D Dee <jayddee246@gmail.com> * Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt> * Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright 2016-2018 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* Copyright 2018 MoneroOcean <https://github.com/MoneroOcean>, <support@moneroocean.stream>
* *
* 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
@ -96,7 +97,8 @@ int xmrig::Controller::init(int argc, char **argv)
{ {
Cpu::init(); Cpu::init();
d_ptr->config = xmrig::Config::load(argc, argv, this); // init pconfig global pointer to config
pconfig = d_ptr->config = xmrig::Config::load(argc, argv, this);
if (!d_ptr->config) { if (!d_ptr->config) {
return 1; return 1;
} }