mirror of
https://github.com/xmrig/xmrig.git
synced 2024-11-18 10:01:06 +00:00
Improved OpenCL profile generation, don't create unnecessary (equal to main profile) profiles.
This commit is contained in:
parent
1d03b942a5
commit
7db7b3727d
6 changed files with 193 additions and 99 deletions
|
@ -49,11 +49,19 @@ public:
|
||||||
inline const T &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 disable(const Algorithm &algo) { m_disabled.insert(algo); }
|
||||||
|
|
||||||
inline void move(const char *profile, T &&threads)
|
inline size_t move(const char *profile, T &&threads)
|
||||||
{
|
{
|
||||||
|
if (has(profile)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t count = threads.count();
|
||||||
|
|
||||||
if (!threads.isEmpty()) {
|
if (!threads.isEmpty()) {
|
||||||
m_profiles.insert({ profile, std::move(threads) });
|
m_profiles.insert({ profile, std::move(threads) });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
const T &get(const String &profileName) const;
|
const T &get(const String &profileName) const;
|
||||||
|
|
|
@ -24,21 +24,18 @@
|
||||||
|
|
||||||
|
|
||||||
#include "backend/opencl/OclConfig.h"
|
#include "backend/opencl/OclConfig.h"
|
||||||
|
#include "backend/opencl/OclConfig_gen.h"
|
||||||
#include "backend/opencl/wrappers/OclLib.h"
|
#include "backend/opencl/wrappers/OclLib.h"
|
||||||
#include "base/io/json/Json.h"
|
#include "base/io/json/Json.h"
|
||||||
#include "base/io/log/Log.h"
|
#include "base/io/log/Log.h"
|
||||||
#include "rapidjson/document.h"
|
#include "rapidjson/document.h"
|
||||||
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
static const char *kAMD = "AMD";
|
static const char *kAMD = "AMD";
|
||||||
static const char *kCache = "cache";
|
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 *kDevicesHint = "devices-hint";
|
||||||
static const char *kEnabled = "enabled";
|
static const char *kEnabled = "enabled";
|
||||||
static const char *kINTEL = "INTEL";
|
static const char *kINTEL = "INTEL";
|
||||||
|
@ -47,69 +44,9 @@ static const char *kNVIDIA = "NVIDIA";
|
||||||
static const char *kPlatform = "platform";
|
static const char *kPlatform = "platform";
|
||||||
|
|
||||||
|
|
||||||
#ifdef XMRIG_ALGO_CN_GPU
|
|
||||||
static const char *kCnGPU = "cn/gpu";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef XMRIG_ALGO_CN_LITE
|
|
||||||
static const char *kCnLite = "cn-lite";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef XMRIG_ALGO_CN_HEAVY
|
|
||||||
static const char *kCnHeavy = "cn-heavy";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef XMRIG_ALGO_CN_PICO
|
|
||||||
static const char *kCnPico = "cn-pico";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef XMRIG_ALGO_RANDOMX
|
|
||||||
static const char *kRx = "rx";
|
|
||||||
static const char *kRxWOW = "rx/wow";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef XMRIG_ALGO_ARGON2
|
|
||||||
//static const char *kArgon2 = "argon2";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
extern template class Threads<OclThreads>;
|
extern template class Threads<OclThreads>;
|
||||||
|
|
||||||
|
|
||||||
static size_t generate(const char *key, Threads<OclThreads> &threads, const Algorithm &algorithm, const std::vector<OclDevice> &devices)
|
|
||||||
{
|
|
||||||
if (threads.has(key) || threads.isExist(algorithm)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
OclThreads profile;
|
|
||||||
for (const OclDevice &device : devices) {
|
|
||||||
device.generate(algorithm, profile);
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t count = profile.count();
|
|
||||||
threads.move(key, std::move(profile));
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -251,39 +188,11 @@ void xmrig::OclConfig::generate()
|
||||||
|
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
|
|
||||||
count += xmrig::generate(kCn, m_threads, Algorithm::CN_0, devices);
|
count += xmrig::generate<Algorithm::CN>(m_threads, devices);
|
||||||
count += xmrig::generate(kCn2, m_threads, Algorithm::CN_2, devices);
|
count += xmrig::generate<Algorithm::CN_LITE>(m_threads, devices);
|
||||||
|
count += xmrig::generate<Algorithm::CN_HEAVY>(m_threads, devices);
|
||||||
if (!m_threads.isExist(Algorithm::CN_0)) {
|
count += xmrig::generate<Algorithm::CN_PICO>(m_threads, devices);
|
||||||
m_threads.disable(Algorithm::CN_0);
|
count += xmrig::generate<Algorithm::RANDOM_X>(m_threads, devices);
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
# ifdef XMRIG_ALGO_CN_GPU
|
|
||||||
count += xmrig::generate(kCnGPU, m_threads, Algorithm::CN_GPU, devices);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifdef XMRIG_ALGO_CN_LITE
|
|
||||||
count += xmrig::generate(kCnLite, m_threads, Algorithm::CN_LITE_1, devices);
|
|
||||||
|
|
||||||
if (!m_threads.isExist(Algorithm::CN_LITE_0)) {
|
|
||||||
m_threads.disable(Algorithm::CN_LITE_0);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifdef XMRIG_ALGO_CN_HEAVY
|
|
||||||
count += xmrig::generate(kCnHeavy, m_threads, Algorithm::CN_HEAVY_0, devices);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifdef XMRIG_ALGO_CN_PICO
|
|
||||||
count += xmrig::generate(kCnPico, m_threads, Algorithm::CN_PICO_0, devices);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifdef XMRIG_ALGO_RANDOMX
|
|
||||||
count += xmrig::generate(kRx, m_threads, Algorithm::RX_0, devices);
|
|
||||||
count += xmrig::generate(kRxWOW, m_threads, Algorithm::RX_WOW, devices);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
m_shouldSave = count > 0;
|
m_shouldSave = count > 0;
|
||||||
}
|
}
|
||||||
|
|
152
src/backend/opencl/OclConfig_gen.h
Normal file
152
src/backend/opencl/OclConfig_gen.h
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
/* XMRig
|
||||||
|
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||||
|
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||||
|
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||||
|
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||||
|
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||||
|
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||||
|
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||||
|
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XMRIG_OCLCONFIG_GEN_H
|
||||||
|
#define XMRIG_OCLCONFIG_GEN_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "backend/common/Threads.h"
|
||||||
|
#include "backend/opencl/OclThreads.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
||||||
|
namespace xmrig {
|
||||||
|
|
||||||
|
|
||||||
|
static inline size_t generate(const char *key, Threads<OclThreads> &threads, const Algorithm &algorithm, const std::vector<OclDevice> &devices)
|
||||||
|
{
|
||||||
|
if (threads.isExist(algorithm)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return threads.move(key, OclThreads(devices, algorithm));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<Algorithm::Family FAMILY>
|
||||||
|
static inline size_t generate(Threads<OclThreads> &, const std::vector<OclDevice> &) { return 0; }
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
size_t inline generate<Algorithm::CN>(Threads<OclThreads> &threads, const std::vector<OclDevice> &devices)
|
||||||
|
{
|
||||||
|
size_t count = 0;
|
||||||
|
|
||||||
|
count += generate("cn", threads, Algorithm::CN_0, devices);
|
||||||
|
count += generate("cn/2", threads, Algorithm::CN_2, devices);
|
||||||
|
|
||||||
|
if (!threads.isExist(Algorithm::CN_0)) {
|
||||||
|
threads.disable(Algorithm::CN_0);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifdef XMRIG_ALGO_CN_GPU
|
||||||
|
count += generate("cn/gpu", threads, Algorithm::CN_GPU, devices);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XMRIG_ALGO_CN_LITE
|
||||||
|
template<>
|
||||||
|
size_t inline generate<Algorithm::CN_LITE>(Threads<OclThreads> &threads, const std::vector<OclDevice> &devices)
|
||||||
|
{
|
||||||
|
size_t count = generate("cn-lite", threads, Algorithm::CN_LITE_1, devices);
|
||||||
|
|
||||||
|
if (!threads.isExist(Algorithm::CN_LITE_0)) {
|
||||||
|
threads.disable(Algorithm::CN_LITE_0);
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XMRIG_ALGO_CN_HEAVY
|
||||||
|
template<>
|
||||||
|
size_t inline generate<Algorithm::CN_HEAVY>(Threads<OclThreads> &threads, const std::vector<OclDevice> &devices)
|
||||||
|
{
|
||||||
|
return generate("cn-heavy", threads, Algorithm::CN_HEAVY_0, devices);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XMRIG_ALGO_CN_PICO
|
||||||
|
template<>
|
||||||
|
size_t inline generate<Algorithm::CN_PICO>(Threads<OclThreads> &threads, const std::vector<OclDevice> &devices)
|
||||||
|
{
|
||||||
|
return generate("cn-pico", threads, Algorithm::CN_PICO_0, devices);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef XMRIG_ALGO_RANDOMX
|
||||||
|
template<>
|
||||||
|
size_t inline generate<Algorithm::RANDOM_X>(Threads<OclThreads> &threads, const std::vector<OclDevice> &devices)
|
||||||
|
{
|
||||||
|
size_t count = 0;
|
||||||
|
|
||||||
|
auto rx = OclThreads(devices, Algorithm::RX_0);
|
||||||
|
auto wow = OclThreads(devices, Algorithm::RX_WOW);
|
||||||
|
auto arq = OclThreads(devices, Algorithm::RX_ARQ);
|
||||||
|
|
||||||
|
if (!threads.isExist(Algorithm::RX_WOW) && wow != rx) {
|
||||||
|
count += threads.move("rx/wow", std::move(wow));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!threads.isExist(Algorithm::RX_ARQ) && arq != rx) {
|
||||||
|
count += threads.move("rx/arq", std::move(arq));
|
||||||
|
}
|
||||||
|
|
||||||
|
count += threads.move("rx", std::move(rx));
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} /* namespace xmrig */
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* XMRIG_OCLCONFIG_GEN_H */
|
|
@ -44,6 +44,24 @@ xmrig::OclThreads::OclThreads(const rapidjson::Value &value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xmrig::OclThreads::OclThreads(const std::vector<OclDevice> &devices, const Algorithm &algorithm)
|
||||||
|
{
|
||||||
|
for (const OclDevice &device : devices) {
|
||||||
|
device.generate(algorithm, *this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool xmrig::OclThreads::isEqual(const OclThreads &other) const
|
||||||
|
{
|
||||||
|
if (isEmpty() && other.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count() == other.count() && std::equal(m_data.begin(), m_data.end(), other.m_data.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
rapidjson::Value xmrig::OclThreads::toJSON(rapidjson::Document &doc) const
|
rapidjson::Value xmrig::OclThreads::toJSON(rapidjson::Document &doc) const
|
||||||
{
|
{
|
||||||
using namespace rapidjson;
|
using namespace rapidjson;
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
|
|
||||||
#include "backend/opencl/OclThread.h"
|
#include "backend/opencl/OclThread.h"
|
||||||
|
#include "backend/opencl/wrappers/OclDevice.h"
|
||||||
|
|
||||||
|
|
||||||
namespace xmrig {
|
namespace xmrig {
|
||||||
|
@ -40,6 +41,7 @@ class OclThreads
|
||||||
public:
|
public:
|
||||||
OclThreads() = default;
|
OclThreads() = default;
|
||||||
OclThreads(const rapidjson::Value &value);
|
OclThreads(const rapidjson::Value &value);
|
||||||
|
OclThreads(const std::vector<OclDevice> &devices, const Algorithm &algorithm);
|
||||||
|
|
||||||
inline bool isEmpty() const { return m_data.empty(); }
|
inline bool isEmpty() const { return m_data.empty(); }
|
||||||
inline const std::vector<OclThread> &data() const { return m_data; }
|
inline const std::vector<OclThread> &data() const { return m_data; }
|
||||||
|
@ -47,6 +49,10 @@ public:
|
||||||
inline void add(OclThread &&thread) { m_data.push_back(thread); }
|
inline void add(OclThread &&thread) { m_data.push_back(thread); }
|
||||||
inline void reserve(size_t capacity) { m_data.reserve(capacity); }
|
inline void reserve(size_t capacity) { m_data.reserve(capacity); }
|
||||||
|
|
||||||
|
inline bool operator!=(const OclThreads &other) const { return !isEqual(other); }
|
||||||
|
inline bool operator==(const OclThreads &other) const { return isEqual(other); }
|
||||||
|
|
||||||
|
bool isEqual(const OclThreads &other) const;
|
||||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -13,6 +13,7 @@ if (WITH_OPENCL)
|
||||||
src/backend/opencl/OclBackend.h
|
src/backend/opencl/OclBackend.h
|
||||||
src/backend/opencl/OclCache.h
|
src/backend/opencl/OclCache.h
|
||||||
src/backend/opencl/OclConfig.h
|
src/backend/opencl/OclConfig.h
|
||||||
|
src/backend/opencl/OclConfig_gen.h
|
||||||
src/backend/opencl/OclGenerator.h
|
src/backend/opencl/OclGenerator.h
|
||||||
src/backend/opencl/OclLaunchData.h
|
src/backend/opencl/OclLaunchData.h
|
||||||
src/backend/opencl/OclThread.h
|
src/backend/opencl/OclThread.h
|
||||||
|
|
Loading…
Reference in a new issue