diff --git a/src/backend/common/Threads.cpp b/src/backend/common/Threads.cpp index 894c404b8..323352d18 100644 --- a/src/backend/common/Threads.cpp +++ b/src/backend/common/Threads.cpp @@ -24,7 +24,7 @@ #include "backend/common/Threads.h" -#include "backend/cpu/CpuThread.h" +#include "backend/cpu/CpuThreads.h" #include "rapidjson/document.h" @@ -38,9 +38,9 @@ static const char *kAsterisk = "*"; template -const std::vector &xmrig::Threads::get(const String &profileName) const +const T &xmrig::Threads::get(const String &profileName) const { - static std::vector empty; + static T empty; if (profileName.isNull() || !has(profileName)) { return empty; } @@ -56,16 +56,9 @@ size_t xmrig::Threads::read(const rapidjson::Value &value) for (auto &member : value.GetObject()) { if (member.value.IsArray()) { - std::vector threads; + T threads(member.value); - for (auto &v : member.value.GetArray()) { - T thread(v); - if (thread.isValid()) { - threads.push_back(std::move(thread)); - } - } - - if (!threads.empty()) { + if (!threads.isEmpty()) { move(member.name.GetString(), std::move(threads)); } @@ -138,13 +131,7 @@ void xmrig::Threads::toJSON(rapidjson::Value &out, rapidjson::Document &doc) auto &allocator = doc.GetAllocator(); for (const auto &kv : m_profiles) { - Value arr(kArrayType); - - for (const T &thread : kv.second) { - arr.PushBack(thread.toJSON(doc), allocator); - } - - out.AddMember(kv.first.toJSON(), arr, allocator); + out.AddMember(kv.first.toJSON(), kv.second.toJSON(doc), allocator); } for (const Algorithm &algo : m_disabled) { @@ -159,6 +146,6 @@ void xmrig::Threads::toJSON(rapidjson::Value &out, rapidjson::Document &doc) namespace xmrig { -template class Threads; +template class Threads; } // namespace xmrig diff --git a/src/backend/common/Threads.h b/src/backend/common/Threads.h index bc9e36fd8..2cb333d6f 100644 --- a/src/backend/common/Threads.h +++ b/src/backend/common/Threads.h @@ -45,18 +45,18 @@ 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 isExist(const Algorithm &algo) const { return isDisabled(algo) || m_aliases.count(algo) > 0 || has(algo.shortName()); } - inline const std::vector &get(const Algorithm &algo, bool strict = false) const { return get(profileName(algo, strict)); } + 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); } - inline void move(const char *profile, std::vector &&threads) { m_profiles.insert({ profile, threads }); } + inline void move(const char *profile, T &&threads) { m_profiles.insert({ profile, threads }); } - const std::vector &get(const String &profileName) const; + const T &get(const String &profileName) const; size_t read(const rapidjson::Value &value); String profileName(const Algorithm &algorithm, bool strict = false) const; void toJSON(rapidjson::Value &out, rapidjson::Document &doc) const; private: std::map m_aliases; - std::map > m_profiles; + std::map m_profiles; std::set m_disabled; }; diff --git a/src/backend/cpu/CpuBackend.cpp b/src/backend/cpu/CpuBackend.cpp index 60ca8cf3b..7f208c383 100644 --- a/src/backend/cpu/CpuBackend.cpp +++ b/src/backend/cpu/CpuBackend.cpp @@ -46,7 +46,7 @@ namespace xmrig { -extern template class Threads; +extern template class Threads; static const char *tag = CYAN_BG_BOLD(" cpu "); @@ -150,7 +150,7 @@ bool xmrig::CpuBackend::isEnabled() const bool xmrig::CpuBackend::isEnabled(const Algorithm &algorithm) const { - return !d_ptr->controller->config()->cpu().threads().get(algorithm).empty(); + return !d_ptr->controller->config()->cpu().threads().get(algorithm).isEmpty(); } diff --git a/src/backend/cpu/CpuConfig.cpp b/src/backend/cpu/CpuConfig.cpp index 582649efc..883ef5065 100644 --- a/src/backend/cpu/CpuConfig.cpp +++ b/src/backend/cpu/CpuConfig.cpp @@ -62,7 +62,7 @@ static const char *kRx = "rx"; static const char *kRxWOW = "rx/wow"; #endif -extern template class Threads; +extern template class Threads; } @@ -103,15 +103,15 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const std::vector xmrig::CpuConfig::get(const Miner *miner, const Algorithm &algorithm) const { std::vector out; - const std::vector &threads = m_threads.get(algorithm); + const CpuThreads &threads = m_threads.get(algorithm); - if (threads.empty()) { + if (threads.isEmpty()) { return out; } - out.reserve(threads.size()); + out.reserve(threads.count()); - for (const CpuThread &thread : threads) { + for (const CpuThread &thread : threads.data()) { out.push_back(CpuLaunchData(miner, algorithm, *this, thread)); } diff --git a/src/backend/cpu/CpuConfig.h b/src/backend/cpu/CpuConfig.h index 5b2f3f862..5aca51884 100644 --- a/src/backend/cpu/CpuConfig.h +++ b/src/backend/cpu/CpuConfig.h @@ -28,7 +28,7 @@ #include "backend/common/Threads.h" #include "backend/cpu/CpuLaunchData.h" -#include "backend/cpu/CpuThread.h" +#include "backend/cpu/CpuThreads.h" #include "crypto/common/Assembly.h" @@ -51,12 +51,12 @@ public: std::vector get(const Miner *miner, const Algorithm &algorithm) const; void read(const rapidjson::Value &value); - inline bool isEnabled() const { return m_enabled; } - inline bool isHugePages() const { return m_hugePages; } - inline bool isShouldSave() const { return m_shouldSave; } - inline const Assembly &assembly() const { return m_assembly; } - inline const Threads &threads() const { return m_threads; } - inline int priority() const { return m_priority; } + inline bool isEnabled() const { return m_enabled; } + inline bool isHugePages() const { return m_hugePages; } + inline bool isShouldSave() const { return m_shouldSave; } + inline const Assembly &assembly() const { return m_assembly; } + inline const Threads &threads() const { return m_threads; } + inline int priority() const { return m_priority; } private: void generate(); @@ -70,7 +70,7 @@ private: bool m_hugePages = true; bool m_shouldSave = false; int m_priority = -1; - Threads m_threads; + Threads m_threads; }; diff --git a/src/backend/cpu/CpuThread.h b/src/backend/cpu/CpuThread.h index adaffa68f..7c7ce4bee 100644 --- a/src/backend/cpu/CpuThread.h +++ b/src/backend/cpu/CpuThread.h @@ -22,11 +22,8 @@ * along with this program. If not, see . */ -#ifndef XMRIG_CPUTHREADCONFIG_H -#define XMRIG_CPUTHREADCONFIG_H - - -#include +#ifndef XMRIG_CPUTHREAD_H +#define XMRIG_CPUTHREAD_H #include "rapidjson/fwd.h" @@ -58,10 +55,7 @@ private: }; -typedef std::vector CpuThreads; - - } /* namespace xmrig */ -#endif /* XMRIG_CPUTHREADCONFIG_H */ +#endif /* XMRIG_CPUTHREAD_H */ diff --git a/src/backend/cpu/CpuThreads.cpp b/src/backend/cpu/CpuThreads.cpp new file mode 100644 index 000000000..f877c9d34 --- /dev/null +++ b/src/backend/cpu/CpuThreads.cpp @@ -0,0 +1,54 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "backend/cpu/CpuThreads.h" +#include "rapidjson/document.h" + + +xmrig::CpuThreads::CpuThreads(const rapidjson::Value &value) +{ + if (value.IsArray()) { + for (auto &v : value.GetArray()) { + CpuThread thread(v); + if (thread.isValid()) { + add(std::move(thread)); + } + } + } +} + + +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); + } + + return array; +} diff --git a/src/backend/cpu/CpuThreads.h b/src/backend/cpu/CpuThreads.h new file mode 100644 index 000000000..3951c202a --- /dev/null +++ b/src/backend/cpu/CpuThreads.h @@ -0,0 +1,63 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2018 XMR-Stak , + * Copyright 2018-2019 SChernykh + * Copyright 2016-2019 XMRig , + * + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef XMRIG_CPUTHREADS_H +#define XMRIG_CPUTHREADS_H + + +#include + + +#include "backend/cpu/CpuThread.h" + + +namespace xmrig { + + +class CpuThreads +{ +public: + inline CpuThreads() {} + inline CpuThreads(size_t count) : m_data(count) {} + + CpuThreads(const rapidjson::Value &value); + + inline bool isEmpty() const { return m_data.empty(); } + inline const std::vector &data() const { return m_data; } + inline size_t count() const { return m_data.size(); } + inline void add(CpuThread &&thread) { m_data.push_back(thread); } + inline void add(int64_t affinity, int intensity = 1) { add(CpuThread(intensity, affinity)); } + inline void reserve(size_t capacity) { m_data.reserve(capacity); } + + rapidjson::Value toJSON(rapidjson::Document &doc) const; + +private: + std::vector m_data; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_CPUTHREADS_H */ diff --git a/src/backend/cpu/cpu.cmake b/src/backend/cpu/cpu.cmake index 2ae73db70..b6c8915b5 100644 --- a/src/backend/cpu/cpu.cmake +++ b/src/backend/cpu/cpu.cmake @@ -4,6 +4,7 @@ set(HEADERS_BACKEND_CPU src/backend/cpu/CpuConfig.h src/backend/cpu/CpuLaunchData.cpp src/backend/cpu/CpuThread.h + src/backend/cpu/CpuThreads.h src/backend/cpu/CpuWorker.h src/backend/cpu/interfaces/ICpuInfo.h ) @@ -14,6 +15,7 @@ set(SOURCES_BACKEND_CPU src/backend/cpu/CpuConfig.cpp src/backend/cpu/CpuLaunchData.h src/backend/cpu/CpuThread.cpp + src/backend/cpu/CpuThreads.cpp src/backend/cpu/CpuWorker.cpp ) diff --git a/src/backend/cpu/interfaces/ICpuInfo.h b/src/backend/cpu/interfaces/ICpuInfo.h index daaa39c30..9bc3b11aa 100644 --- a/src/backend/cpu/interfaces/ICpuInfo.h +++ b/src/backend/cpu/interfaces/ICpuInfo.h @@ -26,7 +26,7 @@ #define XMRIG_CPUINFO_H -#include "backend/cpu/CpuThread.h" +#include "backend/cpu/CpuThreads.h" #include "crypto/common/Assembly.h" #include "crypto/common/Algorithm.h" diff --git a/src/backend/cpu/platform/BasicCpuInfo.cpp b/src/backend/cpu/platform/BasicCpuInfo.cpp index 2b63edbaa..49d4b0059 100644 --- a/src/backend/cpu/platform/BasicCpuInfo.cpp +++ b/src/backend/cpu/platform/BasicCpuInfo.cpp @@ -182,23 +182,25 @@ const char *xmrig::BasicCpuInfo::backend() const xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm) const { - if (threads() == 1) { - return CpuThreads(1); + const size_t count = std::thread::hardware_concurrency(); + + if (count == 1) { + return 1; } # ifdef XMRIG_ALGO_CN_GPU if (algorithm == Algorithm::CN_GPU) { - return CpuThreads(threads()); + return count; } # endif if (algorithm.family() == Algorithm::CN_LITE || algorithm.family() == Algorithm::CN_PICO) { - return CpuThreads(threads()); + return count; } if (algorithm.family() == Algorithm::CN_HEAVY) { - return CpuThreads(std::max(threads() / 4, 1)); + return std::max(count / 4, 1); } - return CpuThreads(std::max(threads() / 2, 1)); + return std::max(count / 2, 1); } diff --git a/src/backend/cpu/platform/HwlocCpuInfo.cpp b/src/backend/cpu/platform/HwlocCpuInfo.cpp index b2aa47d7c..8a9c75d32 100644 --- a/src/backend/cpu/platform/HwlocCpuInfo.cpp +++ b/src/backend/cpu/platform/HwlocCpuInfo.cpp @@ -222,7 +222,7 @@ xmrig::CpuThreads xmrig::HwlocCpuInfo::threads(const Algorithm &algorithm) const processTopLevelCache(cache, algorithm, threads); } - if (threads.empty()) { + if (threads.isEmpty()) { LOG_WARN("hwloc auto configuration for algorithm \"%s\" failed.", algorithm.shortName()); return BasicCpuInfo::threads(algorithm); @@ -286,7 +286,7 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith for (hwloc_obj_t core : cores) { const std::vector units = findByType(core, HWLOC_OBJ_PU); for (hwloc_obj_t pu : units) { - threads.push_back(CpuThread(1, pu->os_index)); + threads.add(pu->os_index); } } @@ -307,7 +307,7 @@ void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorith PUs--; allocated_pu = true; - threads.push_back(CpuThread(1, units[pu_id]->os_index)); + threads.add(units[pu_id]->os_index); if (cacheHashes == 0) { break;