Added support for extended threads and algo-perf config parameters
This commit is contained in:
parent
5f73919be1
commit
a8d399e450
3 changed files with 131 additions and 52 deletions
|
@ -6,6 +6,7 @@
|
|||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* 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 2018 MoneroOcean <https://github.com/MoneroOcean>, <support@moneroocean.stream>
|
||||
*
|
||||
* 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
|
||||
|
@ -36,6 +37,10 @@
|
|||
#include "rapidjson/prettywriter.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 };
|
||||
|
||||
|
@ -48,6 +53,11 @@ xmrig::Config::Config() : xmrig::CommonConfig(),
|
|||
m_maxCpuUsage(75),
|
||||
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("safe", m_safe, allocator);
|
||||
|
||||
if (threadsMode() == Advanced) {
|
||||
Value threads(kArrayType);
|
||||
// save extended "threads" based on m_threads
|
||||
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) {
|
||||
threads.PushBack(thread->toConfig(doc), allocator);
|
||||
for (const IThread *thread : m_threads[pa].list) {
|
||||
threads2.PushBack(thread->toConfig(doc), allocator);
|
||||
}
|
||||
|
||||
threads.AddMember(key, threads2, allocator);
|
||||
}
|
||||
else {
|
||||
threads.AddMember(key, threadsMode(pa) == Automatic ? Value(kNullType) : Value(threadsCount(pa)), allocator);
|
||||
}
|
||||
}
|
||||
doc.AddMember("threads", threads, allocator);
|
||||
|
||||
doc.AddMember("threads", threads, allocator);
|
||||
}
|
||||
else {
|
||||
doc.AddMember("threads", threadsMode() == Automatic ? Value(kNullType) : Value(threadsCount()), 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);
|
||||
|
||||
|
@ -150,34 +176,36 @@ bool xmrig::Config::finalize()
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!m_threads.cpu.empty()) {
|
||||
m_threads.mode = Advanced;
|
||||
const bool softAES = (m_aesMode == AES_AUTO ? (Cpu::hasAES() ? AES_HW : AES_SOFT) : m_aesMode) == AES_SOFT;
|
||||
// parse "threads" into m_threads
|
||||
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;
|
||||
|
||||
for (size_t i = 0; i < m_threads.cpu.size(); ++i) {
|
||||
m_threads.list.push_back(CpuThread::createFromData(i, m_algorithm.algo(), m_threads.cpu[i], m_priority, softAES));
|
||||
for (size_t i = 0; i < m_threads[pa].cpu.size(); ++i) {
|
||||
m_threads[pa].list.push_back(CpuThread::createFromData(i, xmrig::Algorithm(pa).algo(), m_threads[pa].cpu[i], m_priority, softAES));
|
||||
}
|
||||
} else {
|
||||
const AlgoVariant av = getAlgoVariant();
|
||||
m_threads[pa].mode = m_threads[pa].count ? Simple : Automatic;
|
||||
|
||||
const size_t size = CpuThread::multiway(av) * cn_select_memory(xmrig::Algorithm(pa).algo()) / 1024;
|
||||
|
||||
if (!m_threads[pa].count) {
|
||||
m_threads[pa].count = Cpu::optimalThreadsCount(size, m_maxCpuUsage);
|
||||
}
|
||||
else if (m_safe) {
|
||||
const size_t count = Cpu::optimalThreadsCount(size, m_maxCpuUsage);
|
||||
if (m_threads[pa].count > count) {
|
||||
m_threads[pa].count = count;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_threads[pa].count; ++i) {
|
||||
m_threads[pa].list.push_back(CpuThread::createFromAV(i, xmrig::Algorithm(pa).algo(), av, m_threads[pa].mask, m_priority));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const AlgoVariant av = getAlgoVariant();
|
||||
m_threads.mode = m_threads.count ? Simple : Automatic;
|
||||
|
||||
const size_t size = CpuThread::multiway(av) * cn_select_memory(m_algorithm.algo()) / 1024;
|
||||
|
||||
if (!m_threads.count) {
|
||||
m_threads.count = Cpu::optimalThreadsCount(size, m_maxCpuUsage);
|
||||
}
|
||||
else if (m_safe) {
|
||||
const size_t count = Cpu::optimalThreadsCount(size, m_maxCpuUsage);
|
||||
if (m_threads.count > count) {
|
||||
m_threads.count = count;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_threads.count; ++i) {
|
||||
m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm.algo(), av, m_threads.mask, m_priority));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -231,7 +259,7 @@ bool xmrig::Config::parseString(int key, const char *arg)
|
|||
|
||||
case ThreadsKey: /* --threads */
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -260,7 +288,7 @@ bool xmrig::Config::parseUint64(int key, uint64_t arg)
|
|||
switch (key) {
|
||||
case CPUAffinityKey: /* --cpu-affinity */
|
||||
if (arg) {
|
||||
m_threads.mask = arg;
|
||||
m_threads[m_algorithm.perf_algo()].mask = arg; // sets default algo threads
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -272,22 +300,49 @@ bool xmrig::Config::parseUint64(int key, uint64_t arg)
|
|||
}
|
||||
|
||||
|
||||
// parse specific perf algo (or generic) threads config
|
||||
void xmrig::Config::parseThreadsJSON(const rapidjson::Value &threads, const xmrig::PerfAlgo pa)
|
||||
{
|
||||
for (const rapidjson::Value &value : threads.GetArray()) {
|
||||
if (!value.IsObject()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (value.HasMember("low_power_mode")) {
|
||||
auto data = CpuThread::parse(value);
|
||||
|
||||
if (data.valid) {
|
||||
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()) {
|
||||
for (const rapidjson::Value &value : threads.GetArray()) {
|
||||
if (!value.IsObject()) {
|
||||
continue;
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (value.HasMember("low_power_mode")) {
|
||||
auto data = CpuThread::parse(value);
|
||||
|
||||
if (data.valid) {
|
||||
m_threads.cpu.push_back(std::move(data));
|
||||
}
|
||||
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) {
|
||||
case ThreadsKey: /* --threads */
|
||||
if (arg >= 0 && arg < 1024) {
|
||||
m_threads.count = arg;
|
||||
m_threads[m_algorithm.perf_algo()].count = arg; // sets default algo threads
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* 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 2018 MoneroOcean <https://github.com/MoneroOcean>, <support@moneroocean.stream>
|
||||
*
|
||||
* 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
|
||||
|
@ -78,11 +79,25 @@ public:
|
|||
inline AesMode aesMode() const { return m_aesMode; }
|
||||
inline AlgoVariant algoVariant() const { return m_algoVariant; }
|
||||
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 threadsCount() const { return m_threads.list.size(); }
|
||||
inline int64_t affinity() const { return m_threads.mask; }
|
||||
inline ThreadsMode threadsMode() const { return m_threads.mode; }
|
||||
|
||||
// access to m_threads taking into accoun that it is now separated for each perf algo
|
||||
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);
|
||||
|
||||
|
@ -92,6 +107,8 @@ protected:
|
|||
bool parseString(int key, const char *arg) override;
|
||||
bool parseUint64(int key, uint64_t arg) 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:
|
||||
bool parseInt(int key, int arg);
|
||||
|
@ -120,9 +137,14 @@ private:
|
|||
bool m_safe;
|
||||
int m_maxCpuUsage;
|
||||
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 */
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* 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 2018 MoneroOcean <https://github.com/MoneroOcean>, <support@moneroocean.stream>
|
||||
*
|
||||
* 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
|
||||
|
@ -96,7 +97,8 @@ int xmrig::Controller::init(int argc, char **argv)
|
|||
{
|
||||
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) {
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue