Added alternative object format for CPU threads.

This commit is contained in:
XMRig 2019-08-07 18:12:39 +07:00
parent 96fd7545d1
commit 42dc914eec
5 changed files with 106 additions and 46 deletions

View file

@ -9,6 +9,7 @@ Example below demonstrate all primary ideas of flexible profiles configuration:
* `"rx/wow"` Exact match to algorithm `rx/wow`, defined 4 threads without CPU affinity.
* `"cn"` Default failback profile for all `cn/*` algorithms, defined 2 threads with CPU affinity, another failback profiles is `cn-lite`, `cn-heavy` and `rx`.
* `"cn-lite"` Default failback profile for all `cn-lite/*` algorithms, defined 2 double threads with CPU affinity.
* `"cn-pico"` Alternative short object format, since 2.99.5.
* `"custom-profile"` Custom user defined profile.
* `"*"` Failback profile for all unhandled by other profiles algorithms.
* `"cn/r"` Exact match, alias to profile `custom-profile`.
@ -34,6 +35,11 @@ Example below demonstrate all primary ideas of flexible profiles configuration:
"affinity": 2
}
],
"cn-pico": {
"intensity": 2,
"threads": 8,
"affinity": -1
},
"custom-profile": [0, 2],
"*": [-1],
"cn/r": "custom-profile",

View file

@ -55,7 +55,7 @@ size_t xmrig::Threads<T>::read(const rapidjson::Value &value)
using namespace rapidjson;
for (auto &member : value.GetObject()) {
if (member.value.IsArray()) {
if (member.value.IsArray() || member.value.IsObject()) {
T threads(member.value);
if (!threads.isEmpty()) {

View file

@ -23,10 +23,66 @@
*/
#include <algorithm>
#include "backend/cpu/CpuThreads.h"
#include "base/io/json/Json.h"
#include "rapidjson/document.h"
namespace xmrig {
static const char *kAffinity = "affinity";
static const char *kIntensity = "intensity";
static const char *kThreads = "threads";
static inline int64_t getAffinityMask(const rapidjson::Value &value)
{
if (value.IsInt64()) {
return value.GetInt64();
}
if (value.IsString()) {
const char *arg = value.GetString();
const char *p = strstr(arg, "0x");
return p ? strtoll(p, nullptr, 16) : strtoll(arg, nullptr, 10);
}
return -1L;
}
static inline int64_t getAffinity(uint64_t index, int64_t affinity)
{
if (affinity == -1L) {
return -1L;
}
size_t idx = 0;
for (size_t i = 0; i < 64; i++) {
if (!(static_cast<uint64_t>(affinity) & (1ULL << i))) {
continue;
}
if (idx == index) {
return static_cast<int64_t>(i);
}
idx++;
}
return -1L;
}
}
xmrig::CpuThreads::CpuThreads(const rapidjson::Value &value)
{
if (value.IsArray()) {
@ -37,6 +93,20 @@ xmrig::CpuThreads::CpuThreads(const rapidjson::Value &value)
}
}
}
else if (value.IsObject()) {
int intensity = Json::getInt(value, kIntensity, 1);
const size_t threads = std::min<unsigned>(Json::getUint(value, kThreads), 1024);
m_affinity = getAffinityMask(Json::getValue(value, kAffinity));
m_format = ObjectFormat;
if (intensity < 1 || intensity > 5) {
intensity = 1;
}
for (size_t i = 0; i < threads; ++i) {
add(getAffinity(i, m_affinity), intensity);
}
}
}
@ -45,10 +115,22 @@ rapidjson::Value xmrig::CpuThreads::toJSON(rapidjson::Document &doc) const
using namespace rapidjson;
auto &allocator = doc.GetAllocator();
Value array(kArrayType);
for (const CpuThread &thread : m_data) {
array.PushBack(thread.toJSON(doc), allocator);
Value out;
if (m_format == ArrayFormat) {
out.SetArray();
for (const CpuThread &thread : m_data) {
out.PushBack(thread.toJSON(doc), allocator);
}
}
else {
out.SetObject();
out.AddMember(StringRef(kIntensity), m_data.empty() ? 1 : m_data.front().intensity(), allocator);
out.AddMember(StringRef(kThreads), static_cast<unsigned>(m_data.size()), allocator);
out.AddMember(StringRef(kAffinity), m_affinity, allocator);
}
return array;
return out;
}

View file

@ -53,6 +53,13 @@ public:
rapidjson::Value toJSON(rapidjson::Document &doc) const;
private:
enum Format {
ArrayFormat,
ObjectFormat
};
Format m_format = ArrayFormat;
int64_t m_affinity = -1;
std::vector<CpuThread> m_data;
};

View file

@ -36,6 +36,7 @@ static const char *kAffinity = "affinity";
static const char *kAsterisk = "*";
static const char *kCpu = "cpu";
static const char *kIntensity = "intensity";
static const char *kThreads = "threads";
#ifdef XMRIG_ALGO_RANDOMX
static const char *kRandomX = "randomx";
@ -79,30 +80,6 @@ static inline bool isHwAes(uint64_t av)
}
static inline int64_t affinity(uint64_t index, int64_t affinity)
{
if (affinity == -1L) {
return -1L;
}
size_t idx = 0;
for (size_t i = 0; i < 64; i++) {
if (!(static_cast<uint64_t>(affinity) & (1ULL << i))) {
continue;
}
if (idx == index) {
return static_cast<int64_t>(i);
}
idx++;
}
return -1L;
}
}
@ -123,24 +100,12 @@ void xmrig::ConfigTransform::finalize(rapidjson::Document &doc)
doc.AddMember(StringRef(kCpu), Value(kObjectType), allocator);
}
Value threads(kArrayType);
Value profile(kObjectType);
profile.AddMember(StringRef(kIntensity), m_intensity, allocator);
profile.AddMember(StringRef(kThreads), m_threads, allocator);
profile.AddMember(StringRef(kAffinity), m_affinity, allocator);
if (m_intensity > 1) {
for (uint64_t i = 0; i < m_threads; ++i) {
Value thread(kObjectType);
thread.AddMember(StringRef(kIntensity), m_intensity, allocator);
thread.AddMember(StringRef(kAffinity), affinity(i, m_affinity), allocator);
threads.PushBack(thread, doc.GetAllocator());
}
}
else {
for (uint64_t i = 0; i < m_threads; ++i) {
threads.PushBack(affinity(i, m_affinity), doc.GetAllocator());
}
}
doc[kCpu].AddMember(StringRef(kAsterisk), threads, doc.GetAllocator());
doc[kCpu].AddMember(StringRef(kAsterisk), profile, doc.GetAllocator());
}
}