Implemented "asm" option.

This commit is contained in:
XMRig 2018-09-24 14:19:26 +03:00
parent ba65a34a01
commit c2fcf23855
14 changed files with 275 additions and 34 deletions

View file

@ -255,5 +255,5 @@ if (WITH_DEBUG_LOG)
add_definitions(/DAPP_DEBUG) add_definitions(/DAPP_DEBUG)
endif() endif()
add_executable(${PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${HTTPD_SOURCES} ${TLS_SOURCES}) add_executable(${PROJECT_NAME} ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${HTTPD_SOURCES} ${TLS_SOURCES} ${XMRIG_ASM_SOURCES})
target_link_libraries(${PROJECT_NAME} ${XMRIG_ASM_LIBRARY} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB}) target_link_libraries(${PROJECT_NAME} ${XMRIG_ASM_LIBRARY} ${OPENSSL_LIBRARIES} ${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB})

View file

@ -15,8 +15,10 @@ if (WITH_ASM AND NOT XMRIG_ARM)
) )
endif() endif()
set(XMRIG_ASM_SOURCES src/crypto/Asm.h src/crypto/Asm.cpp)
set_property(TARGET ${XMRIG_ASM_LIBRARY} PROPERTY LINKER_LANGUAGE C) set_property(TARGET ${XMRIG_ASM_LIBRARY} PROPERTY LINKER_LANGUAGE C)
else() else()
set(XMRIG_ASM_SOURCES "")
set(XMRIG_ASM_LIBRARY "") set(XMRIG_ASM_LIBRARY "")
add_definitions(/DXMRIG_NO_ASM) add_definitions(/DXMRIG_NO_ASM)
endif() endif()

View file

@ -32,11 +32,28 @@
#include "common/net/Pool.h" #include "common/net/Pool.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/Controller.h" #include "core/Controller.h"
#include "crypto/Asm.h"
#include "Mem.h" #include "Mem.h"
#include "Summary.h" #include "Summary.h"
#include "version.h" #include "version.h"
#ifndef XMRIG_NO_ASM
static const char *coloredAsmNames[] = {
"\x1B[1;31mnone\x1B[0m",
"auto",
"\x1B[1;32mintel\x1B[0m",
"\x1B[1;32mryzen\x1B[0m"
};
inline static const char *asmName(xmrig::Assembly assembly, bool colors)
{
return colors ? coloredAsmNames[assembly] : xmrig::Asm::toString(assembly);
}
#endif
static void print_memory(xmrig::Config *config) { static void print_memory(xmrig::Config *config) {
# ifdef _WIN32 # ifdef _WIN32
if (config->isColors()) { if (config->isColors()) {
@ -101,6 +118,18 @@ static void print_threads(xmrig::Config *config)
config->isColors() && config->donateLevel() == 0 ? "\x1B[1;31m" : "", config->isColors() && config->donateLevel() == 0 ? "\x1B[1;31m" : "",
config->donateLevel()); config->donateLevel());
} }
# ifndef XMRIG_NO_ASM
if (config->assembly() == xmrig::ASM_AUTO) {
const xmrig::Assembly assembly = xmrig::Cpu::info()->assembly();
Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13sauto:%s")
: " * %-13sauto:%s", "ASSEMBLY", asmName(assembly, config->isColors()));
}
else {
Log::i()->text(config->isColors() ? GREEN_BOLD(" * ") WHITE_BOLD("%-13s%s") : " * %-13s%s", "ASSEMBLY", asmName(config->assembly(), config->isColors()));
}
# endif
} }

View file

@ -80,6 +80,7 @@ public:
SafeKey = 1005, SafeKey = 1005,
ThreadsKey = 't', ThreadsKey = 't',
HardwareAESKey = 1011, HardwareAESKey = 1011,
AssemblyKey = 1015,
// xmrig amd // xmrig amd
OclPlatformKey = 1400, OclPlatformKey = 1400,

View file

@ -98,7 +98,8 @@ enum Assembly {
ASM_NONE, ASM_NONE,
ASM_AUTO, ASM_AUTO,
ASM_INTEL, ASM_INTEL,
ASM_RYZEN ASM_RYZEN,
ASM_MAX
}; };

View file

@ -30,6 +30,7 @@
#include "common/cpu/Cpu.h" #include "common/cpu/Cpu.h"
#include "core/Config.h" #include "core/Config.h"
#include "core/ConfigCreator.h" #include "core/ConfigCreator.h"
#include "crypto/Asm.h"
#include "crypto/CryptoNight_constants.h" #include "crypto/CryptoNight_constants.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "rapidjson/filewritestream.h" #include "rapidjson/filewritestream.h"
@ -43,6 +44,7 @@ static char affinity_tmp[20] = { 0 };
xmrig::Config::Config() : xmrig::CommonConfig(), xmrig::Config::Config() : xmrig::CommonConfig(),
m_aesMode(AES_AUTO), m_aesMode(AES_AUTO),
m_algoVariant(AV_AUTO), m_algoVariant(AV_AUTO),
m_assembly(ASM_AUTO),
m_hugePages(true), m_hugePages(true),
m_safe(false), m_safe(false),
m_maxCpuUsage(75), m_maxCpuUsage(75),
@ -51,11 +53,6 @@ xmrig::Config::Config() : xmrig::CommonConfig(),
} }
xmrig::Config::~Config()
{
}
bool xmrig::Config::reload(const char *json) bool xmrig::Config::reload(const char *json)
{ {
return xmrig::ConfigLoader::reload(this, json); return xmrig::ConfigLoader::reload(this, json);
@ -178,7 +175,7 @@ bool xmrig::Config::finalize()
} }
for (size_t i = 0; i < m_threads.count; ++i) { 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)); m_threads.list.push_back(CpuThread::createFromAV(i, m_algorithm.algo(), av, m_threads.mask, m_priority, m_assembly));
} }
return true; return true;
@ -204,6 +201,12 @@ bool xmrig::Config::parseBoolean(int key, bool enable)
m_aesMode = enable ? AES_HW : AES_SOFT; m_aesMode = enable ? AES_HW : AES_SOFT;
break; break;
# ifndef XMRIG_NO_ASM
case AssemblyKey:
m_assembly = Asm::parse(enable);
break;
# endif
default: default:
break; break;
} }
@ -244,6 +247,12 @@ bool xmrig::Config::parseString(int key, const char *arg)
return parseUint64(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10)); return parseUint64(key, p ? strtoull(p, nullptr, 16) : strtoull(arg, nullptr, 10));
} }
# ifndef XMRIG_NO_ASM
case AssemblyKey: /* --asm */
m_assembly = Asm::parse(arg);
break;
# endif
default: default:
break; break;
} }

View file

@ -21,8 +21,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef __CONFIG_H__ #ifndef XMRIG_CONFIG_H
#define __CONFIG_H__ #define XMRIG_CONFIG_H
#include <stdint.h> #include <stdint.h>
@ -69,7 +69,6 @@ public:
Config(); Config();
~Config();
bool reload(const char *json); bool reload(const char *json);
@ -77,6 +76,7 @@ public:
inline AesMode aesMode() const { return m_aesMode; } inline AesMode aesMode() const { return m_aesMode; }
inline AlgoVariant algoVariant() const { return m_algoVariant; } inline AlgoVariant algoVariant() const { return m_algoVariant; }
inline Assembly assembly() const { return m_assembly; }
inline bool isHugePages() const { return m_hugePages; } inline bool isHugePages() const { return m_hugePages; }
inline const std::vector<IThread *> &threads() const { return m_threads.list; } inline const std::vector<IThread *> &threads() const { return m_threads.list; }
inline int priority() const { return m_priority; } inline int priority() const { return m_priority; }
@ -116,6 +116,7 @@ private:
AesMode m_aesMode; AesMode m_aesMode;
AlgoVariant m_algoVariant; AlgoVariant m_algoVariant;
Assembly m_assembly;
bool m_hugePages; bool m_hugePages;
bool m_safe; bool m_safe;
int m_maxCpuUsage; int m_maxCpuUsage;
@ -126,4 +127,4 @@ private:
} /* namespace xmrig */ } /* namespace xmrig */
#endif /* __CONFIG_H__ */ #endif /* XMRIG_CONFIG_H */

View file

@ -135,6 +135,7 @@ static struct option const options[] = {
{ "tls", 0, nullptr, xmrig::IConfig::TlsKey }, { "tls", 0, nullptr, xmrig::IConfig::TlsKey },
{ "tls-fingerprint", 1, nullptr, xmrig::IConfig::FingerprintKey }, { "tls-fingerprint", 1, nullptr, xmrig::IConfig::FingerprintKey },
{ "version", 0, nullptr, xmrig::IConfig::VersionKey }, { "version", 0, nullptr, xmrig::IConfig::VersionKey },
{ "asm", 1, nullptr, xmrig::IConfig::AssemblyKey },
{ nullptr, 0, nullptr, 0 } { nullptr, 0, nullptr, 0 }
}; };
@ -159,6 +160,7 @@ static struct option const config_options[] = {
{ "threads", 1, nullptr, xmrig::IConfig::ThreadsKey }, { "threads", 1, nullptr, xmrig::IConfig::ThreadsKey },
{ "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey }, { "user-agent", 1, nullptr, xmrig::IConfig::UserAgentKey },
{ "hw-aes", 0, nullptr, xmrig::IConfig::HardwareAESKey }, { "hw-aes", 0, nullptr, xmrig::IConfig::HardwareAESKey },
{ "asm", 1, nullptr, xmrig::IConfig::AssemblyKey },
{ nullptr, 0, nullptr, 0 } { nullptr, 0, nullptr, 0 }
}; };

View file

@ -47,7 +47,7 @@ xmrig::AdvancedCpuInfo::AdvancedCpuInfo() :
cpuid_get_raw_data(&raw); cpuid_get_raw_data(&raw);
cpu_identify(&raw, &data); cpu_identify(&raw, &data);
strncpy(m_brand, data.brand_str, sizeof(m_brand) - 1); strncpy(m_brand, data.brand_str, sizeof(m_brand));
m_sockets = threads() / data.num_logical_cpus; m_sockets = threads() / data.num_logical_cpus;
if (m_sockets == 0) { if (m_sockets == 0) {

100
src/crypto/Asm.cpp Normal file
View file

@ -0,0 +1,100 @@
/* 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 2016-2018 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/>.
*/
#include <assert.h>
#include <string.h>
#ifdef _MSC_VER
# define strncasecmp _strnicmp
# define strcasecmp _stricmp
#endif
#include "crypto/Asm.h"
#include "rapidjson/document.h"
static const char *asmNames[] = {
"none",
"auto",
"intel",
"ryzen"
};
xmrig::Assembly xmrig::Asm::parse(const char *assembly, Assembly defaultValue)
{
constexpr size_t const size = sizeof(asmNames) / sizeof((asmNames)[0]);
assert(assembly != nullptr);
assert(ASM_MAX == size);
if (assembly == nullptr) {
return defaultValue;
}
for (size_t i = 0; i < size; i++) {
if (strcasecmp(assembly, asmNames[i]) == 0) {
return static_cast<Assembly>(i);
}
}
return defaultValue;
}
xmrig::Assembly xmrig::Asm::parse(const rapidjson::Value &value, Assembly defaultValue)
{
if (value.IsBool()) {
return parse(value.IsBool());
}
if (value.IsString()) {
return parse(value.GetString(), defaultValue);
}
return defaultValue;
}
const char *xmrig::Asm::toString(Assembly assembly)
{
return asmNames[assembly];
}
rapidjson::Value xmrig::Asm::toJSON(Assembly assembly)
{
using namespace rapidjson;
if (assembly == ASM_NONE) {
return Value(false);
}
if (assembly == ASM_AUTO) {
return Value(true);
}
return Value(StringRef(toString(assembly)));
}

50
src/crypto/Asm.h Normal file
View file

@ -0,0 +1,50 @@
/* 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 2016-2018 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_ASM_H
#define XMRIG_ASM_H
#include "common/xmrig.h"
#include "rapidjson/fwd.h"
namespace xmrig {
class Asm
{
public:
static Assembly parse(const char *assembly, Assembly defaultValue = ASM_AUTO);
static Assembly parse(const rapidjson::Value &value, Assembly defaultValue = ASM_AUTO);
static const char *toString(Assembly assembly);
static rapidjson::Value toJSON(Assembly assembly);
inline static Assembly parse(bool enable) { return enable ? ASM_AUTO : ASM_NONE; }
};
} /* namespace xmrig */
#endif /* XMRIG_ASM_H */

View file

@ -561,6 +561,7 @@ inline void cryptonight_single_hash(const uint8_t *__restrict__ input, size_t si
} }
#ifndef XMRIG_NO_ASM
extern "C" void cnv2_mainloop_ivybridge_asm(cryptonight_ctx *ctx); extern "C" void cnv2_mainloop_ivybridge_asm(cryptonight_ctx *ctx);
extern "C" void cnv2_mainloop_ryzen_asm(cryptonight_ctx *ctx); extern "C" void cnv2_mainloop_ryzen_asm(cryptonight_ctx *ctx);
@ -584,6 +585,7 @@ inline void cryptonight_single_hash_asm(const uint8_t *__restrict__ input, size_
xmrig::keccakf(reinterpret_cast<uint64_t*>(ctx[0]->state), 24); xmrig::keccakf(reinterpret_cast<uint64_t*>(ctx[0]->state), 24);
extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output); extra_hashes[ctx[0]->state[0] & 3](ctx[0]->state, 200, output);
} }
#endif
template<xmrig::Algo ALGO, bool SOFT_AES, xmrig::Variant VARIANT> template<xmrig::Algo ALGO, bool SOFT_AES, xmrig::Variant VARIANT>

View file

@ -24,8 +24,10 @@
#include <assert.h> #include <assert.h>
#include "common/cpu/Cpu.h"
#include "common/log/Log.h" #include "common/log/Log.h"
#include "common/net/Pool.h" #include "common/net/Pool.h"
#include "crypto/Asm.h"
#include "rapidjson/document.h" #include "rapidjson/document.h"
#include "workers/CpuThread.h" #include "workers/CpuThread.h"
@ -37,9 +39,10 @@
#endif #endif
xmrig::CpuThread::CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch) : xmrig::CpuThread::CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly) :
m_algorithm(algorithm), m_algorithm(algorithm),
m_av(av), m_av(av),
m_assembly(assembly),
m_prefetch(prefetch), m_prefetch(prefetch),
m_softAES(softAES), m_softAES(softAES),
m_priority(priority), m_priority(priority),
@ -50,23 +53,23 @@ xmrig::CpuThread::CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiw
} }
xmrig::CpuThread::~CpuThread()
{
}
bool xmrig::CpuThread::isSoftAES(AlgoVariant av) bool xmrig::CpuThread::isSoftAES(AlgoVariant av)
{ {
return av == AV_SINGLE_SOFT || av == AV_DOUBLE_SOFT || av > AV_PENTA; return av == AV_SINGLE_SOFT || av == AV_DOUBLE_SOFT || av > AV_PENTA;
} }
xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant av, Variant variant) xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant av, Variant variant, Assembly assembly)
{ {
assert(variant >= VARIANT_0 && variant < VARIANT_MAX); assert(variant >= VARIANT_0 && variant < VARIANT_MAX);
# ifndef XMRIG_NO_ASM
constexpr const size_t count = VARIANT_MAX * 10 * 3 + 2;
# else
constexpr const size_t count = VARIANT_MAX * 10 * 3; constexpr const size_t count = VARIANT_MAX * 10 * 3;
static const cn_hash_fun func_table[count + 2] = { # endif
static const cn_hash_fun func_table[count] = {
cryptonight_single_hash<CRYPTONIGHT, false, VARIANT_0>, cryptonight_single_hash<CRYPTONIGHT, false, VARIANT_0>,
cryptonight_double_hash<CRYPTONIGHT, false, VARIANT_0>, cryptonight_double_hash<CRYPTONIGHT, false, VARIANT_0>,
cryptonight_single_hash<CRYPTONIGHT, true, VARIANT_0>, cryptonight_single_hash<CRYPTONIGHT, true, VARIANT_0>,
@ -243,13 +246,14 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
# endif # endif
# ifndef XMRIG_NO_ASM
cryptonight_single_hash_asm<CRYPTONIGHT, VARIANT_2, ASM_INTEL>, cryptonight_single_hash_asm<CRYPTONIGHT, VARIANT_2, ASM_INTEL>,
cryptonight_single_hash_asm<CRYPTONIGHT, VARIANT_2, ASM_RYZEN> cryptonight_single_hash_asm<CRYPTONIGHT, VARIANT_2, ASM_RYZEN>
# endif
}; };
const size_t index = VARIANT_MAX * 10 * algorithm + 10 * variant + av - 1;
# ifndef NDEBUG # ifndef NDEBUG
const size_t index = fnIndex(algorithm, av, variant, assembly);
cn_hash_fun func = func_table[index]; cn_hash_fun func = func_table[index];
assert(index < sizeof(func_table) / sizeof(func_table[0])); assert(index < sizeof(func_table) / sizeof(func_table[0]));
@ -257,12 +261,12 @@ xmrig::CpuThread::cn_hash_fun xmrig::CpuThread::fn(Algo algorithm, AlgoVariant a
return func; return func;
# else # else
return func_table[index]; return func_table[fnIndex(algorithm, av, variant, assembly)];
# endif # endif
} }
xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority) xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority, Assembly assembly)
{ {
assert(av > AV_AUTO && av < AV_MAX); assert(av > AV_AUTO && av < AV_MAX);
@ -285,7 +289,7 @@ xmrig::CpuThread *xmrig::CpuThread::createFromAV(size_t index, Algo algorithm, A
} }
} }
return new CpuThread(index, algorithm, av, multiway(av), cpuId, priority, isSoftAES(av), false); return new CpuThread(index, algorithm, av, multiway(av), cpuId, priority, isSoftAES(av), false, assembly);
} }
@ -303,7 +307,7 @@ xmrig::CpuThread *xmrig::CpuThread::createFromData(size_t index, Algo algorithm,
assert(av > AV_AUTO && av < AV_MAX); assert(av > AV_AUTO && av < AV_MAX);
return new CpuThread(index, algorithm, static_cast<AlgoVariant>(av), multiway, data.affinity, priority, softAES, false); return new CpuThread(index, algorithm, static_cast<AlgoVariant>(av), multiway, data.affinity, priority, softAES, false, data.assembly);
} }
@ -325,11 +329,14 @@ xmrig::CpuThread::Data xmrig::CpuThread::parse(const rapidjson::Value &object)
} }
const auto &affinity = object["affine_to_cpu"]; const auto &affinity = object["affine_to_cpu"];
if (affinity.IsUint64()) { if (affinity.IsUint64()) {
data.affinity = affinity.GetInt64(); data.affinity = affinity.GetInt64();
} }
# ifndef XMRIG_NO_ASM
data.assembly = Asm::parse(object["asm"]);
# endif
return data; return data;
} }
@ -371,7 +378,11 @@ void xmrig::CpuThread::print() const
LOG_DEBUG(GREEN_BOLD("CPU thread: ") " index " WHITE_BOLD("%zu") ", multiway " WHITE_BOLD("%d") ", av " WHITE_BOLD("%d") ",", LOG_DEBUG(GREEN_BOLD("CPU thread: ") " index " WHITE_BOLD("%zu") ", multiway " WHITE_BOLD("%d") ", av " WHITE_BOLD("%d") ",",
index(), static_cast<int>(multiway()), static_cast<int>(m_av)); index(), static_cast<int>(multiway()), static_cast<int>(m_av));
# ifndef XMRIG_NO_ASM
LOG_DEBUG(" assembly: %s, affine_to_cpu: %" PRId64, Asm::toString(m_assembly), affinity());
# else
LOG_DEBUG(" affine_to_cpu: %" PRId64, affinity()); LOG_DEBUG(" affine_to_cpu: %" PRId64, affinity());
# endif
} }
#endif #endif
@ -406,5 +417,35 @@ rapidjson::Value xmrig::CpuThread::toConfig(rapidjson::Document &doc) const
obj.AddMember("low_power_mode", multiway(), allocator); obj.AddMember("low_power_mode", multiway(), allocator);
obj.AddMember("affine_to_cpu", affinity() == -1L ? Value(kFalseType) : Value(affinity()), allocator); obj.AddMember("affine_to_cpu", affinity() == -1L ? Value(kFalseType) : Value(affinity()), allocator);
# ifndef XMRIG_NO_ASM
obj.AddMember("asm", Asm::toJSON(m_assembly), allocator);
# endif
return obj; return obj;
} }
size_t xmrig::CpuThread::fnIndex(Algo algorithm, AlgoVariant av, Variant variant, Assembly assembly)
{
const size_t index = VARIANT_MAX * 10 * algorithm + 10 * variant + av - 1;
# ifndef XMRIG_NO_ASM
if (assembly == ASM_AUTO) {
assembly = Cpu::info()->assembly();
}
if (assembly == ASM_NONE) {
return index;
}
constexpr const size_t offset = VARIANT_MAX * 10 * 3;
if (algorithm == CRYPTONIGHT && variant == VARIANT_2) {
if (av == AV_SINGLE) {
return offset + assembly - 2;
}
}
# endif
return index;
}

View file

@ -40,7 +40,7 @@ class CpuThread : public IThread
public: public:
struct Data struct Data
{ {
inline Data() : valid(false), affinity(-1L), multiway(SingleWay) {} inline Data() : assembly(ASM_AUTO), valid(false), affinity(-1L), multiway(SingleWay) {}
inline void setMultiway(int value) inline void setMultiway(int value)
{ {
@ -50,27 +50,27 @@ public:
} }
} }
Assembly assembly;
bool valid; bool valid;
int64_t affinity; int64_t affinity;
Multiway multiway; Multiway multiway;
}; };
CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch); CpuThread(size_t index, Algo algorithm, AlgoVariant av, Multiway multiway, int64_t affinity, int priority, bool softAES, bool prefetch, Assembly assembly);
~CpuThread();
typedef void (*cn_hash_fun)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx **ctx); typedef void (*cn_hash_fun)(const uint8_t *input, size_t size, uint8_t *output, cryptonight_ctx **ctx);
static bool isSoftAES(AlgoVariant av); static bool isSoftAES(AlgoVariant av);
static cn_hash_fun fn(Algo algorithm, AlgoVariant av, Variant variant); static cn_hash_fun fn(Algo algorithm, AlgoVariant av, Variant variant, Assembly assembly);
static CpuThread *createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority); static CpuThread *createFromAV(size_t index, Algo algorithm, AlgoVariant av, int64_t affinity, int priority, Assembly assembly);
static CpuThread *createFromData(size_t index, Algo algorithm, const CpuThread::Data &data, int priority, bool softAES); static CpuThread *createFromData(size_t index, Algo algorithm, const CpuThread::Data &data, int priority, bool softAES);
static Data parse(const rapidjson::Value &object); static Data parse(const rapidjson::Value &object);
static Multiway multiway(AlgoVariant av); static Multiway multiway(AlgoVariant av);
inline bool isPrefetch() const { return m_prefetch; } inline bool isPrefetch() const { return m_prefetch; }
inline bool isSoftAES() const { return m_softAES; } inline bool isSoftAES() const { return m_softAES; }
inline cn_hash_fun fn(Variant variant) const { return fn(m_algorithm, m_av, variant); } inline cn_hash_fun fn(Variant variant) const { return fn(m_algorithm, m_av, variant, m_assembly); }
inline Algo algorithm() const override { return m_algorithm; } inline Algo algorithm() const override { return m_algorithm; }
inline int priority() const override { return m_priority; } inline int priority() const override { return m_priority; }
@ -91,8 +91,11 @@ protected:
rapidjson::Value toConfig(rapidjson::Document &doc) const override; rapidjson::Value toConfig(rapidjson::Document &doc) const override;
private: private:
static size_t fnIndex(Algo algorithm, AlgoVariant av, Variant variant, Assembly assembly);
const Algo m_algorithm; const Algo m_algorithm;
const AlgoVariant m_av; const AlgoVariant m_av;
const Assembly m_assembly;
const bool m_prefetch; const bool m_prefetch;
const bool m_softAES; const bool m_softAES;
const int m_priority; const int m_priority;