Resolved conflicts
This commit is contained in:
commit
d03fb91b0a
82 changed files with 3489 additions and 439 deletions
|
@ -44,6 +44,7 @@ class Threads
|
|||
public:
|
||||
inline bool has(const char *profile) const { return m_profiles.count(profile) > 0; }
|
||||
inline bool isDisabled(const Algorithm &algo) const { return m_disabled.count(algo) > 0; }
|
||||
inline bool isEmpty() const { return m_profiles.empty(); }
|
||||
inline bool isExist(const Algorithm &algo) const { return isDisabled(algo) || m_aliases.count(algo) > 0 || has(algo.shortName()); }
|
||||
inline const T &get(const Algorithm &algo, bool strict = false) const { return get(profileName(algo, strict)); }
|
||||
inline void disable(const Algorithm &algo) { m_disabled.insert(algo); }
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#define XMRIG_PCITOPOLOGY_H
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
#include "base/tools/String.h"
|
||||
|
@ -40,19 +40,30 @@ class PciTopology
|
|||
{
|
||||
public:
|
||||
PciTopology() = default;
|
||||
PciTopology(uint32_t bus, uint32_t device, uint32_t function) : bus(bus), device(device), function(function) {}
|
||||
PciTopology(uint32_t bus, uint32_t device, uint32_t function) : m_valid(true), m_bus(bus), m_device(device), m_function(function) {}
|
||||
|
||||
uint32_t bus = 0;
|
||||
uint32_t device = 0;
|
||||
uint32_t function = 0;
|
||||
inline bool isValid() const { return m_valid; }
|
||||
inline uint8_t bus() const { return m_bus; }
|
||||
inline uint8_t device() const { return m_device; }
|
||||
inline uint8_t function() const { return m_function; }
|
||||
|
||||
String toString() const
|
||||
{
|
||||
if (!isValid()) {
|
||||
return "n/a";
|
||||
}
|
||||
|
||||
char *buf = new char[8]();
|
||||
snprintf(buf, 8, "%02x:%02x.%01x", bus, device, function);
|
||||
snprintf(buf, 8, "%02hhx:%02hhx.%01hhx", bus(), device(), function());
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_valid = false;
|
||||
uint8_t m_bus = 0;
|
||||
uint8_t m_device = 0;
|
||||
uint8_t m_function = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <cassert>
|
||||
|
||||
|
||||
#include "backend/cpu/Cpu.h"
|
||||
|
@ -44,7 +44,15 @@ static xmrig::ICpuInfo *cpuInfo = nullptr;
|
|||
|
||||
xmrig::ICpuInfo *xmrig::Cpu::info()
|
||||
{
|
||||
assert(cpuInfo != nullptr);
|
||||
if (cpuInfo == nullptr) {
|
||||
# if defined(XMRIG_FEATURE_HWLOC)
|
||||
cpuInfo = new HwlocCpuInfo();
|
||||
# elif defined(XMRIG_FEATURE_LIBCPUID)
|
||||
cpuInfo = new AdvancedCpuInfo();
|
||||
# else
|
||||
cpuInfo = new BasicCpuInfo();
|
||||
# endif
|
||||
}
|
||||
|
||||
return cpuInfo;
|
||||
}
|
||||
|
@ -62,7 +70,7 @@ rapidjson::Value xmrig::Cpu::toJSON(rapidjson::Document &doc)
|
|||
cpu.AddMember("brand", StringRef(i->brand()), allocator);
|
||||
cpu.AddMember("aes", i->hasAES(), allocator);
|
||||
cpu.AddMember("avx2", i->hasAVX2(), allocator);
|
||||
cpu.AddMember("x64", i->isX64(), allocator);
|
||||
cpu.AddMember("x64", ICpuInfo::isX64(), allocator);
|
||||
cpu.AddMember("l2", static_cast<uint64_t>(i->L2()), allocator);
|
||||
cpu.AddMember("l3", static_cast<uint64_t>(i->L3()), allocator);
|
||||
cpu.AddMember("cores", static_cast<uint64_t>(i->cores()), allocator);
|
||||
|
@ -81,20 +89,6 @@ rapidjson::Value xmrig::Cpu::toJSON(rapidjson::Document &doc)
|
|||
}
|
||||
|
||||
|
||||
void xmrig::Cpu::init()
|
||||
{
|
||||
assert(cpuInfo == nullptr);
|
||||
|
||||
# if defined(XMRIG_FEATURE_HWLOC)
|
||||
cpuInfo = new HwlocCpuInfo();
|
||||
# elif defined(XMRIG_FEATURE_LIBCPUID)
|
||||
cpuInfo = new AdvancedCpuInfo();
|
||||
# else
|
||||
cpuInfo = new BasicCpuInfo();
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Cpu::release()
|
||||
{
|
||||
assert(cpuInfo != nullptr);
|
||||
|
|
|
@ -37,7 +37,6 @@ class Cpu
|
|||
public:
|
||||
static ICpuInfo *info();
|
||||
static rapidjson::Value toJSON(rapidjson::Document &doc);
|
||||
static void init();
|
||||
static void release();
|
||||
|
||||
inline static Assembly::Id assembly(Assembly::Id hint) { return hint == Assembly::AUTO ? Cpu::info()->assembly() : hint; }
|
||||
|
|
|
@ -35,6 +35,7 @@ static const char *kCn = "cn";
|
|||
static const char *kEnabled = "enabled";
|
||||
static const char *kHugePages = "huge-pages";
|
||||
static const char *kHwAes = "hw-aes";
|
||||
static const char *kMaxThreadsHint = "max-threads-hint";
|
||||
static const char *kPriority = "priority";
|
||||
|
||||
#ifdef XMRIG_FEATURE_ASM
|
||||
|
@ -73,11 +74,6 @@ extern template class Threads<CpuThreads>;
|
|||
}
|
||||
|
||||
|
||||
xmrig::CpuConfig::CpuConfig()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::CpuConfig::isHwAES() const
|
||||
{
|
||||
return (m_aes == AES_AUTO ? (Cpu::info()->hasAES() ? AES_HW : AES_SOFT) : m_aes) == AES_HW;
|
||||
|
@ -96,6 +92,10 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const
|
|||
obj.AddMember(StringRef(kHwAes), m_aes == AES_AUTO ? Value(kNullType) : Value(m_aes == AES_HW), allocator);
|
||||
obj.AddMember(StringRef(kPriority), priority() != -1 ? Value(priority()) : Value(kNullType), allocator);
|
||||
|
||||
if (m_threads.isEmpty()) {
|
||||
obj.AddMember(StringRef(kMaxThreadsHint), m_limit, allocator);
|
||||
}
|
||||
|
||||
# ifdef XMRIG_FEATURE_ASM
|
||||
obj.AddMember(StringRef(kAsm), m_assembly.toJSON(), allocator);
|
||||
# endif
|
||||
|
@ -132,8 +132,9 @@ std::vector<xmrig::CpuLaunchData> xmrig::CpuConfig::get(const Miner *miner, cons
|
|||
void xmrig::CpuConfig::read(const rapidjson::Value &value, uint32_t version)
|
||||
{
|
||||
if (value.IsObject()) {
|
||||
m_enabled = Json::getBool(value, kEnabled, m_enabled);
|
||||
m_hugePages = Json::getBool(value, kHugePages, m_hugePages);
|
||||
m_enabled = Json::getBool(value, kEnabled, m_enabled);
|
||||
m_hugePages = Json::getBool(value, kHugePages, m_hugePages);
|
||||
m_limit = Json::getUint(value, kMaxThreadsHint, m_limit);
|
||||
|
||||
setAesMode(Json::getValue(value, kHwAes));
|
||||
setPriority(Json::getInt(value, kPriority, -1));
|
||||
|
@ -169,29 +170,29 @@ void xmrig::CpuConfig::generate()
|
|||
ICpuInfo *cpu = Cpu::info();
|
||||
|
||||
m_threads.disable(Algorithm::CN_0);
|
||||
m_threads.move(kCn, cpu->threads(Algorithm::CN_0));
|
||||
m_threads.move(kCn, cpu->threads(Algorithm::CN_0, m_limit));
|
||||
|
||||
# ifdef XMRIG_ALGO_CN_GPU
|
||||
m_threads.move(kCnGPU, cpu->threads(Algorithm::CN_GPU));
|
||||
m_threads.move(kCnGPU, cpu->threads(Algorithm::CN_GPU, m_limit));
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_CN_LITE
|
||||
m_threads.disable(Algorithm::CN_LITE_0);
|
||||
m_threads.move(kCnLite, cpu->threads(Algorithm::CN_LITE_1));
|
||||
m_threads.move(kCnLite, cpu->threads(Algorithm::CN_LITE_1, m_limit));
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_CN_HEAVY
|
||||
m_threads.move(kCnHeavy, cpu->threads(Algorithm::CN_HEAVY_0));
|
||||
m_threads.move(kCnHeavy, cpu->threads(Algorithm::CN_HEAVY_0, m_limit));
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_CN_PICO
|
||||
m_threads.move(kCnPico, cpu->threads(Algorithm::CN_PICO_0));
|
||||
m_threads.move(kCnPico, cpu->threads(Algorithm::CN_PICO_0, m_limit));
|
||||
# endif
|
||||
|
||||
# ifdef XMRIG_ALGO_RANDOMX
|
||||
m_threads.move(kRx, cpu->threads(Algorithm::RX_0));
|
||||
m_threads.move(kRxWOW, cpu->threads(Algorithm::RX_WOW));
|
||||
m_threads.move(kDefyX, cpu->threads(Algorithm::DEFYX));
|
||||
m_threads.move(kRx, cpu->threads(Algorithm::RX_0, m_limit));
|
||||
m_threads.move(kRxWOW, cpu->threads(Algorithm::RX_WOW, m_limit));
|
||||
m_threads.move(kDefyX, cpu->threads(Algorithm::DEFYX, m_limit));
|
||||
# endif
|
||||
|
||||
generateArgon2();
|
||||
|
@ -201,7 +202,7 @@ void xmrig::CpuConfig::generate()
|
|||
void xmrig::CpuConfig::generateArgon2()
|
||||
{
|
||||
# ifdef XMRIG_ALGO_ARGON2
|
||||
m_threads.move(kArgon2, Cpu::info()->threads(Algorithm::AR2_CHUKWA));
|
||||
m_threads.move(kArgon2, Cpu::info()->threads(Algorithm::AR2_CHUKWA, m_limit));
|
||||
# endif
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
AES_SOFT
|
||||
};
|
||||
|
||||
CpuConfig();
|
||||
CpuConfig() = default;
|
||||
|
||||
bool isHwAES() const;
|
||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||
|
@ -74,6 +74,7 @@ private:
|
|||
int m_priority = -1;
|
||||
String m_argon2Impl;
|
||||
Threads<CpuThreads> m_threads;
|
||||
uint32_t m_limit = 100;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -45,18 +45,18 @@ public:
|
|||
inline constexpr static bool isX64() { return false; }
|
||||
# endif
|
||||
|
||||
virtual Assembly::Id assembly() const = 0;
|
||||
virtual bool hasAES() const = 0;
|
||||
virtual bool hasAVX2() const = 0;
|
||||
virtual const char *backend() const = 0;
|
||||
virtual const char *brand() const = 0;
|
||||
virtual CpuThreads threads(const Algorithm &algorithm) const = 0;
|
||||
virtual size_t cores() const = 0;
|
||||
virtual size_t L2() const = 0;
|
||||
virtual size_t L3() const = 0;
|
||||
virtual size_t nodes() const = 0;
|
||||
virtual size_t packages() const = 0;
|
||||
virtual size_t threads() const = 0;
|
||||
virtual Assembly::Id assembly() const = 0;
|
||||
virtual bool hasAES() const = 0;
|
||||
virtual bool hasAVX2() const = 0;
|
||||
virtual const char *backend() const = 0;
|
||||
virtual const char *brand() const = 0;
|
||||
virtual CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const = 0;
|
||||
virtual size_t cores() const = 0;
|
||||
virtual size_t L2() const = 0;
|
||||
virtual size_t L3() const = 0;
|
||||
virtual size_t nodes() const = 0;
|
||||
virtual size_t packages() const = 0;
|
||||
virtual size_t threads() const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -23,10 +23,10 @@
|
|||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
#include "3rdparty/libcpuid/libcpuid.h"
|
||||
|
@ -109,7 +109,7 @@ xmrig::AdvancedCpuInfo::AdvancedCpuInfo() :
|
|||
}
|
||||
|
||||
|
||||
xmrig::CpuThreads xmrig::AdvancedCpuInfo::threads(const Algorithm &algorithm) const
|
||||
xmrig::CpuThreads xmrig::AdvancedCpuInfo::threads(const Algorithm &algorithm, uint32_t limit) const
|
||||
{
|
||||
if (threads() == 1) {
|
||||
return 1;
|
||||
|
@ -153,5 +153,12 @@ xmrig::CpuThreads xmrig::AdvancedCpuInfo::threads(const Algorithm &algorithm) co
|
|||
}
|
||||
# endif
|
||||
|
||||
return CpuThreads(std::max<size_t>(std::min<size_t>(count, threads()), 1), intensity);
|
||||
if (limit > 0 && limit < 100) {
|
||||
count = std::min(count, static_cast<size_t>(round(threads() * (limit / 100.0))));
|
||||
}
|
||||
else {
|
||||
count = std::min(count, threads());
|
||||
}
|
||||
|
||||
return CpuThreads(std::max<size_t>(count, 1), intensity);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
AdvancedCpuInfo();
|
||||
|
||||
protected:
|
||||
CpuThreads threads(const Algorithm &algorithm) const override;
|
||||
CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const override;
|
||||
|
||||
inline Assembly::Id assembly() const override { return m_assembly; }
|
||||
inline bool hasAES() const override { return m_aes; }
|
||||
|
|
|
@ -179,7 +179,7 @@ const char *xmrig::BasicCpuInfo::backend() const
|
|||
}
|
||||
|
||||
|
||||
xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm) const
|
||||
xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm, uint32_t limit) const
|
||||
{
|
||||
const size_t count = std::thread::hardware_concurrency();
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
|
||||
protected:
|
||||
const char *backend() const override;
|
||||
CpuThreads threads(const Algorithm &algorithm) const override;
|
||||
CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const override;
|
||||
|
||||
inline Assembly::Id assembly() const override { return m_assembly; }
|
||||
inline bool hasAES() const override { return m_aes; }
|
||||
|
|
|
@ -63,7 +63,7 @@ const char *xmrig::BasicCpuInfo::backend() const
|
|||
}
|
||||
|
||||
|
||||
xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &) const
|
||||
xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &, uint32_t) const
|
||||
{
|
||||
return CpuThreads(threads());
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <hwloc.h>
|
||||
|
||||
|
||||
|
@ -127,9 +128,7 @@ static inline bool isCacheExclusive(hwloc_obj_t obj)
|
|||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::HwlocCpuInfo::HwlocCpuInfo() : BasicCpuInfo(),
|
||||
m_backend(),
|
||||
m_cache()
|
||||
xmrig::HwlocCpuInfo::HwlocCpuInfo()
|
||||
{
|
||||
m_threads = 0;
|
||||
|
||||
|
@ -149,7 +148,7 @@ xmrig::HwlocCpuInfo::HwlocCpuInfo() : BasicCpuInfo(),
|
|||
# endif
|
||||
|
||||
const std::vector<hwloc_obj_t> packages = findByType(hwloc_get_root_obj(m_topology), HWLOC_OBJ_PACKAGE);
|
||||
if (packages.size()) {
|
||||
if (!packages.empty()) {
|
||||
const char *value = hwloc_obj_get_info_by_name(packages[0], "CPUModel");
|
||||
if (value) {
|
||||
strncpy(m_brand, value, 64);
|
||||
|
@ -202,10 +201,10 @@ xmrig::HwlocCpuInfo::~HwlocCpuInfo()
|
|||
}
|
||||
|
||||
|
||||
xmrig::CpuThreads xmrig::HwlocCpuInfo::threads(const Algorithm &algorithm) const
|
||||
xmrig::CpuThreads xmrig::HwlocCpuInfo::threads(const Algorithm &algorithm, uint32_t limit) const
|
||||
{
|
||||
if (L2() == 0 && L3() == 0) {
|
||||
return BasicCpuInfo::threads(algorithm);
|
||||
return BasicCpuInfo::threads(algorithm, limit);
|
||||
}
|
||||
|
||||
const unsigned depth = L3() > 0 ? 3 : 2;
|
||||
|
@ -218,21 +217,37 @@ xmrig::CpuThreads xmrig::HwlocCpuInfo::threads(const Algorithm &algorithm) const
|
|||
|
||||
findCache(hwloc_get_root_obj(m_topology), depth, depth, [&caches](hwloc_obj_t found) { caches.emplace_back(found); });
|
||||
|
||||
for (hwloc_obj_t cache : caches) {
|
||||
processTopLevelCache(cache, algorithm, threads);
|
||||
if (limit > 0 && limit < 100 && !caches.empty()) {
|
||||
const double maxTotalThreads = round(m_threads * (limit / 100.0));
|
||||
const auto maxPerCache = std::max(static_cast<int>(round(maxTotalThreads / caches.size())), 1);
|
||||
int remaining = std::max(static_cast<int>(maxTotalThreads), 1);
|
||||
|
||||
for (hwloc_obj_t cache : caches) {
|
||||
processTopLevelCache(cache, algorithm, threads, std::min(maxPerCache, remaining));
|
||||
|
||||
remaining -= maxPerCache;
|
||||
if (remaining <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (hwloc_obj_t cache : caches) {
|
||||
processTopLevelCache(cache, algorithm, threads, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (threads.isEmpty()) {
|
||||
LOG_WARN("hwloc auto configuration for algorithm \"%s\" failed.", algorithm.shortName());
|
||||
|
||||
return BasicCpuInfo::threads(algorithm);
|
||||
return BasicCpuInfo::threads(algorithm, limit);
|
||||
}
|
||||
|
||||
return threads;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorithm &algorithm, CpuThreads &threads) const
|
||||
void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorithm &algorithm, CpuThreads &threads, size_t limit) const
|
||||
{
|
||||
constexpr size_t oneMiB = 1024u * 1024u;
|
||||
|
||||
|
@ -296,6 +311,10 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith
|
|||
}
|
||||
# endif
|
||||
|
||||
if (limit > 0) {
|
||||
cacheHashes = std::min(cacheHashes, limit);
|
||||
}
|
||||
|
||||
if (cacheHashes >= PUs) {
|
||||
for (hwloc_obj_t core : cores) {
|
||||
const std::vector<hwloc_obj_t> units = findByType(core, HWLOC_OBJ_PU);
|
||||
|
|
|
@ -27,10 +27,11 @@
|
|||
|
||||
|
||||
#include "backend/cpu/platform/BasicCpuInfo.h"
|
||||
#include "base/tools/Object.h"
|
||||
|
||||
|
||||
typedef struct hwloc_obj *hwloc_obj_t;
|
||||
typedef struct hwloc_topology *hwloc_topology_t;
|
||||
using hwloc_obj_t = struct hwloc_obj *;
|
||||
using hwloc_topology_t = struct hwloc_topology *;
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
@ -39,6 +40,9 @@ namespace xmrig {
|
|||
class HwlocCpuInfo : public BasicCpuInfo
|
||||
{
|
||||
public:
|
||||
XMRIG_DISABLE_COPY_MOVE(HwlocCpuInfo)
|
||||
|
||||
|
||||
enum Feature : uint32_t {
|
||||
SET_THISTHREAD_MEMBIND = 1
|
||||
};
|
||||
|
@ -51,7 +55,7 @@ public:
|
|||
static inline const std::vector<uint32_t> &nodeIndexes() { return m_nodeIndexes; }
|
||||
|
||||
protected:
|
||||
CpuThreads threads(const Algorithm &algorithm) const override;
|
||||
CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const override;
|
||||
|
||||
inline const char *backend() const override { return m_backend; }
|
||||
inline size_t cores() const override { return m_cores; }
|
||||
|
@ -61,17 +65,17 @@ protected:
|
|||
inline size_t packages() const override { return m_packages; }
|
||||
|
||||
private:
|
||||
void processTopLevelCache(hwloc_obj_t obj, const Algorithm &algorithm, CpuThreads &threads) const;
|
||||
void processTopLevelCache(hwloc_obj_t obj, const Algorithm &algorithm, CpuThreads &threads, size_t limit) const;
|
||||
|
||||
static std::vector<uint32_t> m_nodeIndexes;
|
||||
static uint32_t m_features;
|
||||
|
||||
char m_backend[20];
|
||||
hwloc_topology_t m_topology;
|
||||
size_t m_cache[5];
|
||||
size_t m_cores = 0;
|
||||
size_t m_nodes = 0;
|
||||
size_t m_packages = 0;
|
||||
char m_backend[20] = { 0 };
|
||||
hwloc_topology_t m_topology = nullptr;
|
||||
size_t m_cache[5] = { 0 };
|
||||
size_t m_cores = 0;
|
||||
size_t m_nodes = 0;
|
||||
size_t m_packages = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -135,6 +135,10 @@ public:
|
|||
return printDisabled(RED_S " (failed to load OpenCL runtime)");
|
||||
}
|
||||
|
||||
if (platform.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
platform = cl.platform();
|
||||
if (!platform.isValid()) {
|
||||
return printDisabled(RED_S " (selected OpenCL platform NOT found)");
|
||||
|
@ -150,7 +154,7 @@ public:
|
|||
for (const OclDevice &device : devices) {
|
||||
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") CYAN_BOLD("#%zu") YELLOW(" %s") " %s " WHITE_BOLD("%uMHz") " cu:" WHITE_BOLD("%u") " mem:" CYAN("%zu/%zu") " MB", "OPENCL GPU",
|
||||
device.index(),
|
||||
device.hasTopology() ? device.topology().toString().data() : "n/a",
|
||||
device.topology().toString().data(),
|
||||
device.printableName().data(),
|
||||
device.clock(),
|
||||
device.computeUnits(),
|
||||
|
@ -177,7 +181,7 @@ public:
|
|||
CYAN_BOLD("%3u") " |" CYAN_BOLD("%3s") " |" CYAN_BOLD("%3u") " |" CYAN("%5zu") " | %s",
|
||||
i,
|
||||
data.thread.index(),
|
||||
data.device.hasTopology() ? data.device.topology().toString().data() : "n/a",
|
||||
data.device.topology().toString().data(),
|
||||
data.thread.intensity(),
|
||||
data.thread.worksize(),
|
||||
data.thread.stridedIndex(),
|
||||
|
@ -285,7 +289,7 @@ void xmrig::OclBackend::printHashrate(bool details)
|
|||
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),
|
||||
data.device.index(),
|
||||
data.device.hasTopology() ? data.device.topology().toString().data() : "n/a",
|
||||
data.device.topology().toString().data(),
|
||||
data.device.printableName().data()
|
||||
);
|
||||
|
||||
|
@ -302,12 +306,15 @@ void xmrig::OclBackend::printHashrate(bool details)
|
|||
|
||||
void xmrig::OclBackend::setJob(const Job &job)
|
||||
{
|
||||
const OclConfig &cl = d_ptr->controller->config()->cl();
|
||||
if (cl.isEnabled()) {
|
||||
d_ptr->init(cl);
|
||||
}
|
||||
|
||||
if (!isEnabled()) {
|
||||
return stop();
|
||||
}
|
||||
|
||||
const OclConfig &cl = d_ptr->controller->config()->cl();
|
||||
|
||||
std::vector<OclLaunchData> threads = cl.get(d_ptr->controller->miner(), job.algorithm(), d_ptr->platform, d_ptr->devices, tag);
|
||||
if (!d_ptr->threads.empty() && d_ptr->threads.size() == threads.size() && std::equal(d_ptr->threads.begin(), d_ptr->threads.end(), threads.begin())) {
|
||||
return;
|
||||
|
@ -401,6 +408,8 @@ rapidjson::Value xmrig::OclBackend::toJSON(rapidjson::Document &doc) const
|
|||
thread.AddMember("affinity", data.affinity, allocator);
|
||||
thread.AddMember("hashrate", hashrate()->toJSON(i, doc), allocator);
|
||||
|
||||
data.device.toJSON(thread, doc);
|
||||
|
||||
i++;
|
||||
threads.PushBack(thread, allocator);
|
||||
}
|
||||
|
|
|
@ -30,12 +30,16 @@
|
|||
#include "rapidjson/document.h"
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
static const char *kAMD = "AMD";
|
||||
static const char *kCache = "cache";
|
||||
static const char *kCn = "cn";
|
||||
static const char *kCn2 = "cn/2";
|
||||
static const char *kDevicesHint = "devices-hint";
|
||||
static const char *kEnabled = "enabled";
|
||||
static const char *kINTEL = "INTEL";
|
||||
static const char *kLoader = "loader";
|
||||
|
@ -90,6 +94,22 @@ static size_t generate(const char *key, Threads<OclThreads> &threads, const Algo
|
|||
}
|
||||
|
||||
|
||||
static inline std::vector<OclDevice> filterDevices(const std::vector<OclDevice> &devices, const std::vector<uint32_t> &hints)
|
||||
{
|
||||
std::vector<OclDevice> out;
|
||||
out.reserve(std::min(devices.size(), hints.size()));
|
||||
|
||||
for (const auto &device : devices) {
|
||||
auto it = std::find(hints.begin(), hints.end(), device.index());
|
||||
if (it != hints.end()) {
|
||||
out.emplace_back(device);
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -214,17 +234,20 @@ void xmrig::OclConfig::read(const rapidjson::Value &value)
|
|||
m_loader = Json::getString(value, kLoader);
|
||||
|
||||
setPlatform(Json::getValue(value, kPlatform));
|
||||
setDevicesHint(Json::getString(value, kDevicesHint));
|
||||
|
||||
if (isEnabled()) {
|
||||
m_threads.read(value);
|
||||
m_threads.read(value);
|
||||
|
||||
generate();
|
||||
}
|
||||
generate();
|
||||
}
|
||||
else if (value.IsBool() && value.IsFalse()) {
|
||||
m_enabled = false;
|
||||
else if (value.IsBool()) {
|
||||
m_enabled = value.GetBool();
|
||||
|
||||
generate();
|
||||
}
|
||||
else {
|
||||
m_shouldSave = true;
|
||||
|
||||
generate();
|
||||
}
|
||||
}
|
||||
|
@ -232,11 +255,15 @@ void xmrig::OclConfig::read(const rapidjson::Value &value)
|
|||
|
||||
void xmrig::OclConfig::generate()
|
||||
{
|
||||
if (!isEnabled() || m_threads.has("*")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!OclLib::init(loader())) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto devices = platform().devices();
|
||||
const auto devices = m_devicesHint.empty() ? platform().devices() : filterDevices(platform().devices(), m_devicesHint);
|
||||
if (devices.empty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -281,6 +308,21 @@ void xmrig::OclConfig::generate()
|
|||
}
|
||||
|
||||
|
||||
void xmrig::OclConfig::setDevicesHint(const char *devicesHint)
|
||||
{
|
||||
if (devicesHint == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto indexes = String(devicesHint).split(',');
|
||||
m_devicesHint.reserve(indexes.size());
|
||||
|
||||
for (const auto &index : indexes) {
|
||||
m_devicesHint.push_back(strtoul(index, nullptr, 10));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::OclConfig::setPlatform(const rapidjson::Value &platform)
|
||||
{
|
||||
if (platform.IsString()) {
|
||||
|
|
|
@ -53,11 +53,13 @@ public:
|
|||
|
||||
private:
|
||||
void generate();
|
||||
void setDevicesHint(const char *devicesHint);
|
||||
void setPlatform(const rapidjson::Value &platform);
|
||||
|
||||
bool m_cache = true;
|
||||
bool m_enabled = true;
|
||||
bool m_enabled = false;
|
||||
bool m_shouldSave = false;
|
||||
std::vector<uint32_t> m_devicesHint;
|
||||
String m_loader;
|
||||
String m_platformVendor;
|
||||
Threads<OclThreads> m_threads;
|
||||
|
|
|
@ -52,6 +52,10 @@ static const char* kDatasetHost = "dataset_host";
|
|||
|
||||
xmrig::OclThread::OclThread(const rapidjson::Value &value)
|
||||
{
|
||||
if (!value.IsObject()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_index = Json::getUint(value, kIndex);
|
||||
m_worksize = std::max(std::min(Json::getUint(value, kWorksize), 128u), 1u);
|
||||
m_unrollFactor = std::max(std::min(Json::getUint(value, kUnroll, m_unrollFactor), 128u), 1u);
|
||||
|
|
|
@ -237,7 +237,7 @@ private:
|
|||
for (size_t i = 0; i < OclCnR::kHeightChunkSize; ++i) {
|
||||
V4_Instruction code[256];
|
||||
const int code_size = v4_random_math_init<Algorithm::CN_R>(code, offset + i);
|
||||
const std::string kernel = std::regex_replace(cryptonight_r_cl, std::regex("XMRIG_INCLUDE_RANDOM_MATH"), getCode(code, code_size));
|
||||
const std::string kernel = std::regex_replace(std::string(cryptonight_r_cl), std::regex("XMRIG_INCLUDE_RANDOM_MATH"), getCode(code, code_size));
|
||||
|
||||
source += std::regex_replace(kernel, std::regex("KERNEL_NAME"), "cn1_" + std::to_string(offset + i));
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ extern bool ocl_vega_cn_generator(const OclDevice &device, const Algorithm &algo
|
|||
extern bool ocl_generic_cn_generator(const OclDevice &device, const Algorithm &algorithm, OclThreads &threads);
|
||||
|
||||
|
||||
ocl_gen_config_fun generators[] = {
|
||||
static ocl_gen_config_fun generators[] = {
|
||||
# ifdef XMRIG_ALGO_RANDOMX
|
||||
ocl_generic_rx_generator,
|
||||
# endif
|
||||
|
@ -142,16 +142,14 @@ xmrig::OclDevice::OclDevice(uint32_t index, cl_device_id id, cl_platform_id plat
|
|||
topology_amd topology;
|
||||
|
||||
if (OclLib::getDeviceInfo(id, 0x4037 /* CL_DEVICE_TOPOLOGY_AMD */, sizeof(topology), &topology, nullptr) == CL_SUCCESS && topology.raw.type == 1) {
|
||||
m_topology = true;
|
||||
m_pciTopology = PciTopology(static_cast<uint32_t>(topology.pcie.bus), static_cast<uint32_t>(topology.pcie.device), static_cast<uint32_t>(topology.pcie.function));
|
||||
m_topology = PciTopology(static_cast<uint32_t>(topology.pcie.bus), static_cast<uint32_t>(topology.pcie.device), static_cast<uint32_t>(topology.pcie.function));
|
||||
}
|
||||
}
|
||||
else if (m_vendorId == OCL_VENDOR_NVIDIA) {
|
||||
cl_uint bus = 0;
|
||||
if (OclLib::getDeviceInfo(id, 0x4008 /* CL_DEVICE_PCI_BUS_ID_NV */, sizeof (bus), &bus, nullptr) == CL_SUCCESS) {
|
||||
m_topology = true;
|
||||
cl_uint slot = OclLib::getUint(id, 0x4009 /* CL_DEVICE_PCI_SLOT_ID_NV */);
|
||||
m_pciTopology = PciTopology(bus, (slot >> 3) & 0xff, slot & 7);
|
||||
m_topology = PciTopology(bus, (slot >> 3) & 0xff, slot & 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -205,3 +203,18 @@ void xmrig::OclDevice::generate(const Algorithm &algorithm, OclThreads &threads)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_API
|
||||
void xmrig::OclDevice::toJSON(rapidjson::Value &out, rapidjson::Document &doc) const
|
||||
{
|
||||
using namespace rapidjson;
|
||||
auto &allocator = doc.GetAllocator();
|
||||
|
||||
out.AddMember("board", board().toJSON(doc), allocator);
|
||||
out.AddMember("name", name().toJSON(doc), allocator);
|
||||
out.AddMember("bus_id", topology().toString().toJSON(doc), allocator);
|
||||
out.AddMember("cu", computeUnits(), allocator);
|
||||
out.AddMember("global_mem", static_cast<uint64_t>(globalMemSize()), allocator);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -69,10 +69,9 @@ public:
|
|||
uint32_t clock() const;
|
||||
void generate(const Algorithm &algorithm, OclThreads &threads) const;
|
||||
|
||||
inline bool hasTopology() const { return m_topology; }
|
||||
inline bool isValid() const { return m_id != nullptr && m_platform != nullptr; }
|
||||
inline cl_device_id id() const { return m_id; }
|
||||
inline const PciTopology &topology() const { return m_pciTopology; }
|
||||
inline const PciTopology &topology() const { return m_topology; }
|
||||
inline const String &board() const { return m_board.isNull() ? m_name : m_board; }
|
||||
inline const String &name() const { return m_name; }
|
||||
inline const String &vendor() const { return m_vendor; }
|
||||
|
@ -81,8 +80,11 @@ public:
|
|||
inline uint32_t computeUnits() const { return m_computeUnits; }
|
||||
inline uint32_t index() const { return m_index; }
|
||||
|
||||
# ifdef XMRIG_FEATURE_API
|
||||
void toJSON(rapidjson::Value &out, rapidjson::Document &doc) const;
|
||||
# endif
|
||||
|
||||
private:
|
||||
bool m_topology = false;
|
||||
cl_device_id m_id = nullptr;
|
||||
cl_platform_id m_platform = nullptr;
|
||||
const String m_board;
|
||||
|
@ -91,7 +93,7 @@ private:
|
|||
const uint32_t m_computeUnits = 1;
|
||||
const uint32_t m_index = 0;
|
||||
OclVendor m_vendorId = OCL_VENDOR_UNKNOWN;
|
||||
PciTopology m_pciTopology;
|
||||
PciTopology m_topology;
|
||||
Type m_type = Unknown;
|
||||
};
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ rapidjson::Value xmrig::OclPlatform::toJSON(rapidjson::Document &doc) const
|
|||
}
|
||||
|
||||
Value out(kObjectType);
|
||||
out.AddMember("index", index(), allocator);
|
||||
out.AddMember("index", static_cast<uint64_t>(index()), allocator);
|
||||
out.AddMember("profile", profile().toJSON(doc), allocator);
|
||||
out.AddMember("version", version().toJSON(doc), allocator);
|
||||
out.AddMember("name", name().toJSON(doc), allocator);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue