diff --git a/CMakeLists.txt b/CMakeLists.txt index 543836c86..f8a56c488 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -54,6 +54,7 @@ set(HEADERS_CRYPTO src/crypto/cn/c_jh.h src/crypto/cn/c_skein.h src/crypto/cn/CnAlgo.h + src/crypto/cn/CnCtx.h src/crypto/cn/CnHash.h src/crypto/cn/CryptoNight_monero.h src/crypto/cn/CryptoNight_test.h @@ -100,6 +101,7 @@ set(SOURCES_CRYPTO src/crypto/cn/c_groestl.c src/crypto/cn/c_jh.c src/crypto/cn/c_skein.c + src/crypto/cn/CnCtx.cpp src/crypto/cn/CnHash.cpp src/crypto/common/Algorithm.cpp src/crypto/common/keccak.cpp diff --git a/src/Mem.cpp b/src/Mem.cpp index e8eabe3b2..5fcea306f 100644 --- a/src/Mem.cpp +++ b/src/Mem.cpp @@ -24,59 +24,8 @@ */ -#include - - -#include "crypto/cn/CryptoNight.h" -#include "crypto/common/portable/mm_malloc.h" -#include "crypto/common/VirtualMemory.h" #include "Mem.h" bool Mem::m_enabled = true; int Mem::m_flags = 0; - - -MemInfo Mem::create(cryptonight_ctx **ctx, const xmrig::Algorithm &algorithm, size_t count) -{ - using namespace xmrig; - - constexpr CnAlgo props; - - MemInfo info; - info.size = props.memory(algorithm.id()) * count; - - constexpr const size_t align_size = 2 * 1024 * 1024; - info.size = ((info.size + align_size - 1) / align_size) * align_size; - info.pages = info.size / align_size; - - allocate(info, m_enabled); - - for (size_t i = 0; i < count; ++i) { - cryptonight_ctx *c = static_cast(_mm_malloc(sizeof(cryptonight_ctx), 4096)); - c->memory = info.memory + (i * props.memory(algorithm.id())); - - c->generated_code = reinterpret_cast(VirtualMemory::allocateExecutableMemory(0x4000)); - c->generated_code_data.algo = Algorithm::INVALID; - c->generated_code_data.height = std::numeric_limits::max(); - - ctx[i] = c; - } - - return info; -} - - -void Mem::release(cryptonight_ctx **ctx, size_t count, MemInfo &info) -{ - if (info.memory == nullptr) { - return; - } - - release(info); - - for (size_t i = 0; i < count; ++i) { - _mm_free(ctx[i]); - } -} - diff --git a/src/Mem.h b/src/Mem.h index 5c60d281c..8e5c418b2 100644 --- a/src/Mem.h +++ b/src/Mem.h @@ -56,9 +56,7 @@ public: Lock = 4 }; - static MemInfo create(cryptonight_ctx **ctx, const xmrig::Algorithm &algorithm, size_t count); static void init(bool enabled); - static void release(cryptonight_ctx **ctx, size_t count, MemInfo &info); static inline bool isHugepagesAvailable() { return (m_flags & HugepagesAvailable) != 0; } diff --git a/src/api/v1/ApiRouter.cpp b/src/api/v1/ApiRouter.cpp index 48a92c938..2e6a815c1 100644 --- a/src/api/v1/ApiRouter.cpp +++ b/src/api/v1/ApiRouter.cpp @@ -144,7 +144,7 @@ void xmrig::ApiRouter::getMiner(rapidjson::Value &reply, rapidjson::Document &do reply.AddMember("kind", APP_KIND, allocator); reply.AddMember("ua", StringRef(Platform::userAgent()), allocator); reply.AddMember("cpu", cpu, allocator); - reply.AddMember("hugepages", WorkersLegacy::hugePages() > 0, allocator); + reply.AddMember("hugepages", false, allocator); // FIXME hugepages reply.AddMember("donate_level", m_base->config()->pools().donateLevel(), allocator); } diff --git a/src/backend/common/Worker.h b/src/backend/common/Worker.h index 3223a60c5..faebf128c 100644 --- a/src/backend/common/Worker.h +++ b/src/backend/common/Worker.h @@ -42,9 +42,10 @@ class Worker : public IWorker public: Worker(size_t id, int64_t affinity, int priority); - inline size_t id() const override { return m_id; } - inline uint64_t hashCount() const override { return m_hashCount.load(std::memory_order_relaxed); } - inline uint64_t timestamp() const override { return m_timestamp.load(std::memory_order_relaxed); } + inline const VirtualMemory *memory() const override { return nullptr; } + inline size_t id() const override { return m_id; } + inline uint64_t hashCount() const override { return m_hashCount.load(std::memory_order_relaxed); } + inline uint64_t timestamp() const override { return m_timestamp.load(std::memory_order_relaxed); } protected: void storeStats(); diff --git a/src/backend/common/interfaces/IWorker.h b/src/backend/common/interfaces/IWorker.h index de22de020..5c99680b2 100644 --- a/src/backend/common/interfaces/IWorker.h +++ b/src/backend/common/interfaces/IWorker.h @@ -32,16 +32,20 @@ namespace xmrig { +class VirtualMemory; + + class IWorker { public: virtual ~IWorker() = default; - virtual bool selfTest() = 0; - virtual size_t id() const = 0; - virtual uint64_t hashCount() const = 0; - virtual uint64_t timestamp() const = 0; - virtual void start() = 0; + virtual bool selfTest() = 0; + virtual const VirtualMemory *memory() const = 0; + virtual size_t id() const = 0; + virtual uint64_t hashCount() const = 0; + virtual uint64_t timestamp() const = 0; + virtual void start() = 0; }; diff --git a/src/backend/cpu/CpuBackend.cpp b/src/backend/cpu/CpuBackend.cpp index c8d38ca65..a04638323 100644 --- a/src/backend/cpu/CpuBackend.cpp +++ b/src/backend/cpu/CpuBackend.cpp @@ -136,14 +136,10 @@ void xmrig::CpuBackend::printHashrate(bool details) void xmrig::CpuBackend::setJob(const Job &job) { - LOG_WARN("PROFILE %s %zu", d_ptr->controller->config()->cpu().threads().profileName(job.algorithm()).data(), job.algorithm().memory()); - if (d_ptr->isReady(job.algorithm())) { return; } - LOG_INFO(GREEN_BOLD_S "INIT"); - const CpuConfig &cpu = d_ptr->controller->config()->cpu(); const Threads &threads = cpu.threads(); @@ -151,7 +147,11 @@ void xmrig::CpuBackend::setJob(const Job &job) d_ptr->profileName = threads.profileName(job.algorithm()); d_ptr->threads = threads.get(d_ptr->profileName); - LOG_INFO(BLUE_BG_S " %zu ", d_ptr->threads.size()); + LOG_INFO(GREEN_BOLD("CPU") " use profile " BLUE_BG(WHITE_BOLD_S " %s ") WHITE_BOLD_S " (" CYAN_BOLD("%zu") WHITE_BOLD(" threads)") " scratchpad " CYAN_BOLD("%zu KB"), + d_ptr->profileName.data(), + d_ptr->threads.size(), + d_ptr->algo.memory() / 1024 + ); d_ptr->workers.stop(); diff --git a/src/backend/cpu/CpuWorker.cpp b/src/backend/cpu/CpuWorker.cpp index 96466252f..356dfb1b3 100644 --- a/src/backend/cpu/CpuWorker.cpp +++ b/src/backend/cpu/CpuWorker.cpp @@ -29,8 +29,10 @@ #include "backend/cpu/CpuWorker.h" #include "core/Miner.h" +#include "crypto/cn/CnCtx.h" #include "crypto/cn/CryptoNight_test.h" #include "crypto/common/Nonce.h" +#include "crypto/common/VirtualMemory.h" #include "crypto/rx/Rx.h" #include "crypto/rx/RxVm.h" #include "net/JobResults.h" @@ -56,18 +58,18 @@ xmrig::CpuWorker::CpuWorker(size_t index, const CpuLaunchData &data) : m_assembly(data.assembly), m_hwAES(data.hwAES), m_av(data.av()), - m_miner(data.miner) + m_miner(data.miner), + m_ctx() { - if (m_algorithm.family() != Algorithm::RANDOM_X) { - m_memory = Mem::create(m_ctx, m_algorithm, N); - } + m_memory = new VirtualMemory(m_algorithm.memory() * N, data.hugePages); } template xmrig::CpuWorker::~CpuWorker() { - Mem::release(m_ctx, N, m_memory); + CnCtx::release(m_ctx, N); + delete m_memory; # ifdef XMRIG_ALGO_RANDOMX delete m_vm; @@ -81,7 +83,7 @@ void xmrig::CpuWorker::allocateRandomX_VM() { if (!m_vm) { RxDataset *dataset = Rx::dataset(m_job.currentJob().seedHash(), m_job.currentJob().algorithm()); - m_vm = new RxVm(dataset, true, !m_hwAES); + m_vm = new RxVm(dataset, m_memory->scratchpad(), !m_hwAES); } } #endif @@ -90,6 +92,14 @@ void xmrig::CpuWorker::allocateRandomX_VM() template bool xmrig::CpuWorker::selfTest() { +# ifdef XMRIG_ALGO_RANDOMX + if (m_algorithm.family() == Algorithm::RANDOM_X) { + return true; + } +# endif + + allocateCnCtx(); + if (m_algorithm.family() == Algorithm::CN) { const bool rc = verify(Algorithm::CN_0, test_output_v0) && verify(Algorithm::CN_1, test_output_v1) && @@ -136,12 +146,6 @@ bool xmrig::CpuWorker::selfTest() } # endif -# ifdef XMRIG_ALGO_RANDOMX - if (m_algorithm.family() == Algorithm::RANDOM_X) { - return true; - } -# endif - return false; } @@ -172,7 +176,6 @@ void xmrig::CpuWorker::start() # ifdef XMRIG_ALGO_RANDOMX if (job.algorithm().family() == Algorithm::RANDOM_X) { - allocateRandomX_VM(); randomx_calculate_hash(m_vm->get(), m_job.blob(), job.size(), m_hash); } else @@ -262,10 +265,29 @@ bool CpuWorker<1>::verify2(const Algorithm &algorithm, const uint8_t *referenceV } // namespace xmrig +template +void xmrig::CpuWorker::allocateCnCtx() +{ + if (m_ctx[0] == nullptr) { + CnCtx::create(m_ctx, m_memory->scratchpad(), m_memory->size(), N); + } +} + + template void xmrig::CpuWorker::consumeJob() { m_job.add(m_miner->job(), Nonce::sequence(Nonce::CPU), kReserveCount); + +# ifdef XMRIG_ALGO_RANDOMX + if (m_job.currentJob().algorithm().family() == Algorithm::RANDOM_X) { + allocateRandomX_VM(); + } + else +# endif + { + allocateCnCtx(); + } } diff --git a/src/backend/cpu/CpuWorker.h b/src/backend/cpu/CpuWorker.h index c67d355be..c0f9dfafa 100644 --- a/src/backend/cpu/CpuWorker.h +++ b/src/backend/cpu/CpuWorker.h @@ -48,12 +48,12 @@ public: CpuWorker(size_t index, const CpuLaunchData &data); ~CpuWorker() override; - inline const MemInfo &memory() const { return m_memory; } - protected: bool selfTest() override; void start() override; + inline const VirtualMemory *memory() const override { return m_memory; } + private: inline cn_hash_fun fn(const Algorithm &algorithm) const { return CnHash::fn(algorithm, m_av, m_assembly); } @@ -63,6 +63,7 @@ private: bool verify(const Algorithm &algorithm, const uint8_t *referenceValue); bool verify2(const Algorithm &algorithm, const uint8_t *referenceValue); + void allocateCnCtx(); void consumeJob(); const Algorithm m_algorithm; @@ -71,8 +72,8 @@ private: const CnHash::AlgoVariant m_av; const Miner *m_miner; cryptonight_ctx *m_ctx[N]; - MemInfo m_memory; uint8_t m_hash[N * 32]; + VirtualMemory *m_memory = nullptr; WorkerJob m_job; # ifdef XMRIG_ALGO_RANDOMX diff --git a/src/crypto/cn/CnCtx.cpp b/src/crypto/cn/CnCtx.cpp new file mode 100644 index 000000000..5d41bca0d --- /dev/null +++ b/src/crypto/cn/CnCtx.cpp @@ -0,0 +1,60 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2019 XMR-Stak , + * Copyright 2018 Lee Clagett + * 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 + + +#include "crypto/cn/CnCtx.h" +#include "crypto/cn/CryptoNight.h" +#include "crypto/common/Algorithm.h" +#include "crypto/common/portable/mm_malloc.h" +#include "crypto/common/VirtualMemory.h" + + +void xmrig::CnCtx::create(cryptonight_ctx **ctx, uint8_t *memory, size_t size, size_t count) +{ + for (size_t i = 0; i < count; ++i) { + cryptonight_ctx *c = static_cast(_mm_malloc(sizeof(cryptonight_ctx), 4096)); + c->memory = memory + (i * size); + + c->generated_code = reinterpret_cast(VirtualMemory::allocateExecutableMemory(0x4000)); + c->generated_code_data.algo = Algorithm::INVALID; + c->generated_code_data.height = std::numeric_limits::max(); + + ctx[i] = c; + } +} + + +void xmrig::CnCtx::release(cryptonight_ctx **ctx, size_t count) +{ + if (ctx[0] == nullptr) { + return; + } + + for (size_t i = 0; i < count; ++i) { + _mm_free(ctx[i]); + } +} diff --git a/src/crypto/cn/CnCtx.h b/src/crypto/cn/CnCtx.h new file mode 100644 index 000000000..7b0adbec2 --- /dev/null +++ b/src/crypto/cn/CnCtx.h @@ -0,0 +1,52 @@ +/* XMRig + * Copyright 2010 Jeff Garzik + * Copyright 2012-2014 pooler + * Copyright 2014 Lucas Jones + * Copyright 2014-2016 Wolf9466 + * Copyright 2016 Jay D Dee + * Copyright 2017-2019 XMR-Stak , + * Copyright 2018 Lee Clagett + * 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_CN_CTX_H +#define XMRIG_CN_CTX_H + + +#include +#include + + +struct cryptonight_ctx; + + +namespace xmrig +{ + + +class CnCtx +{ +public: + static void create(cryptonight_ctx **ctx, uint8_t *memory, size_t size, size_t count); + static void release(cryptonight_ctx **ctx, size_t count); +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_CN_CTX_H */ diff --git a/src/crypto/common/VirtualMemory.h b/src/crypto/common/VirtualMemory.h index a83c35ed2..98212e404 100644 --- a/src/crypto/common/VirtualMemory.h +++ b/src/crypto/common/VirtualMemory.h @@ -38,6 +38,15 @@ namespace xmrig { class VirtualMemory { public: + inline VirtualMemory() {} + VirtualMemory(size_t size, bool hugePages = true, size_t align = 64); + ~VirtualMemory(); + + inline bool isHugePages() const { return m_flags & HUGEPAGES; } + inline size_t hugePages() const { return isHugePages() ? (align(size()) / 2097152) : 0; } + inline size_t size() const { return m_size; } + inline uint8_t *scratchpad() const { return m_scratchpad; } + static void *allocateExecutableMemory(size_t size); static void *allocateLargePagesMemory(size_t size); static void flushInstructionCache(void *p, size_t size); @@ -46,6 +55,17 @@ public: static void unprotectExecutableMemory(void *p, size_t size); static inline constexpr size_t align(size_t pos, size_t align = 2097152) { return ((pos - 1) / align + 1) * align; } + +private: + enum Flags { + HUGEPAGES_AVAILABLE = 1, + HUGEPAGES = 2, + LOCK = 4 + }; + + int m_flags = 0; + size_t m_size = 0; + uint8_t *m_scratchpad = nullptr; }; diff --git a/src/crypto/common/VirtualMemory_unix.cpp b/src/crypto/common/VirtualMemory_unix.cpp index beac976d0..665fc02b3 100644 --- a/src/crypto/common/VirtualMemory_unix.cpp +++ b/src/crypto/common/VirtualMemory_unix.cpp @@ -29,6 +29,7 @@ #include +#include "crypto/common/portable/mm_malloc.h" #include "crypto/common/VirtualMemory.h" @@ -37,6 +38,47 @@ #endif +xmrig::VirtualMemory::VirtualMemory(size_t size, bool hugePages, size_t align) : + m_size(VirtualMemory::align(size)) +{ + if (hugePages) { + m_scratchpad = static_cast(allocateLargePagesMemory(m_size)); + if (m_scratchpad) { + m_flags |= HUGEPAGES; + + madvise(m_scratchpad, size, MADV_RANDOM | MADV_WILLNEED); + + if (mlock(m_scratchpad, m_size) == 0) { + m_flags |= LOCK; + } + + return; + } + } + + m_scratchpad = static_cast(_mm_malloc(m_size, align)); +} + + +xmrig::VirtualMemory::~VirtualMemory() +{ + if (!m_scratchpad) { + return; + } + + if (isHugePages()) { + if (m_flags & LOCK) { + munlock(m_scratchpad, m_size); + } + + freeLargePagesMemory(m_scratchpad, m_size); + } + else { + _mm_free(m_scratchpad); + } +} + + void *xmrig::VirtualMemory::allocateExecutableMemory(size_t size) { diff --git a/src/crypto/common/VirtualMemory_win.cpp b/src/crypto/common/VirtualMemory_win.cpp index 7f1d6f436..7aa98f891 100644 --- a/src/crypto/common/VirtualMemory_win.cpp +++ b/src/crypto/common/VirtualMemory_win.cpp @@ -32,6 +32,37 @@ #include "crypto/common/VirtualMemory.h" +xmrig::VirtualMemory::VirtualMemory(size_t size, bool hugePages, size_t align) : + m_size(VirtualMemory::align(size)) +{ + if (hugePages) { + m_scratchpad = static_cast(allocateLargePagesMemory(m_size)); + if (m_scratchpad) { + m_flags |= HUGEPAGES; + + return; + } + } + + m_scratchpad = static_cast(_mm_malloc(m_size, align)); +} + + +xmrig::VirtualMemory::~VirtualMemory() +{ + if (!m_scratchpad) { + return; + } + + if (isHugePages()) { + freeLargePagesMemory(m_scratchpad, m_size); + } + else { + _mm_free(m_scratchpad); + } +} + + void *xmrig::VirtualMemory::allocateExecutableMemory(size_t size) { return VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); diff --git a/src/crypto/randomx/randomx.cpp b/src/crypto/randomx/randomx.cpp index dde838b98..df5fc9cbb 100644 --- a/src/crypto/randomx/randomx.cpp +++ b/src/crypto/randomx/randomx.cpp @@ -345,7 +345,7 @@ extern "C" { delete dataset; } - randomx_vm *randomx_create_vm(randomx_flags flags, randomx_cache *cache, randomx_dataset *dataset) { + randomx_vm *randomx_create_vm(randomx_flags flags, randomx_cache *cache, randomx_dataset *dataset, uint8_t *scratchpad) { assert(cache != nullptr || (flags & RANDOMX_FLAG_FULL_MEM)); assert(cache == nullptr || cache->isInitialized()); assert(dataset != nullptr || !(flags & RANDOMX_FLAG_FULL_MEM)); @@ -353,7 +353,7 @@ extern "C" { randomx_vm *vm = nullptr; try { - switch (flags & (RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES)) { + switch (flags & (RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES)) { case RANDOMX_FLAG_DEFAULT: vm = new randomx::InterpretedLightVmDefault(); break; @@ -386,49 +386,19 @@ extern "C" { vm = new randomx::CompiledVmHardAes(); break; - case RANDOMX_FLAG_LARGE_PAGES: - vm = new randomx::InterpretedLightVmLargePage(); - break; - - case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_LARGE_PAGES: - vm = new randomx::InterpretedVmLargePage(); - break; - - case RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES: - vm = new randomx::CompiledLightVmLargePage(); - break; - - case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES: - vm = new randomx::CompiledVmLargePage(); - break; - - case RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES: - vm = new randomx::InterpretedLightVmLargePageHardAes(); - break; - - case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES: - vm = new randomx::InterpretedVmLargePageHardAes(); - break; - - case RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES: - vm = new randomx::CompiledLightVmLargePageHardAes(); - break; - - case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES: - vm = new randomx::CompiledVmLargePageHardAes(); - break; - default: UNREACHABLE; } - if(cache != nullptr) + if (cache != nullptr) { vm->setCache(cache); + } - if(dataset != nullptr) + if (dataset != nullptr) { vm->setDataset(dataset); + } - vm->allocate(); + vm->setScratchpad(scratchpad); } catch (std::exception &ex) { delete vm; diff --git a/src/crypto/randomx/randomx.h b/src/crypto/randomx/randomx.h index cd07ac64c..d688189fe 100644 --- a/src/crypto/randomx/randomx.h +++ b/src/crypto/randomx/randomx.h @@ -286,7 +286,7 @@ RANDOMX_EXPORT void randomx_release_dataset(randomx_dataset *dataset); * (3) cache parameter is NULL and RANDOMX_FLAG_FULL_MEM is not set * (4) dataset parameter is NULL and RANDOMX_FLAG_FULL_MEM is set */ -RANDOMX_EXPORT randomx_vm *randomx_create_vm(randomx_flags flags, randomx_cache *cache, randomx_dataset *dataset); +RANDOMX_EXPORT randomx_vm *randomx_create_vm(randomx_flags flags, randomx_cache *cache, randomx_dataset *dataset, uint8_t *scratchpad); /** * Reinitializes a virtual machine with a new Cache. This function should be called anytime diff --git a/src/crypto/randomx/virtual_machine.cpp b/src/crypto/randomx/virtual_machine.cpp index caa1efbfa..6560dc950 100644 --- a/src/crypto/randomx/virtual_machine.cpp +++ b/src/crypto/randomx/virtual_machine.cpp @@ -95,43 +95,35 @@ void randomx_vm::initialize() { namespace randomx { - alignas(16) volatile static rx_vec_i128 aesDummy; - - template - VmBase::~VmBase() { - Allocator::freeMemory(scratchpad, RANDOMX_SCRATCHPAD_L3_MAX_SIZE); + template + VmBase::~VmBase() { } - template - void VmBase::allocate() { - if (datasetPtr == nullptr) + template + void VmBase::setScratchpad(uint8_t *scratchpad) { + if (datasetPtr == nullptr) { throw std::invalid_argument("Cache/Dataset not set"); - if (!softAes) { //if hardware AES is not supported, it's better to fail now than to return a ticking bomb - rx_vec_i128 tmp = rx_load_vec_i128((const rx_vec_i128*)&aesDummy); - tmp = rx_aesenc_vec_i128(tmp, tmp); - rx_store_vec_i128((rx_vec_i128*)&aesDummy, tmp); } - scratchpad = (uint8_t*)Allocator::allocMemory(RANDOMX_SCRATCHPAD_L3_MAX_SIZE); + + this->scratchpad = scratchpad; } - template - void VmBase::getFinalResult(void* out, size_t outSize) { + template + void VmBase::getFinalResult(void* out, size_t outSize) { hashAes1Rx4(scratchpad, ScratchpadSize, ®.a); blake2b(out, outSize, ®, sizeof(RegisterFile), nullptr, 0); } - template - void VmBase::initScratchpad(void* seed) { + template + void VmBase::initScratchpad(void* seed) { fillAes1Rx4(seed, ScratchpadSize, scratchpad); } - template - void VmBase::generateProgram(void* seed) { + template + void VmBase::generateProgram(void* seed) { fillAes4Rx4(seed, sizeof(program), &program); } - template class VmBase, false>; - template class VmBase, true>; - template class VmBase; - template class VmBase; -} \ No newline at end of file + template class VmBase; + template class VmBase; +} diff --git a/src/crypto/randomx/virtual_machine.hpp b/src/crypto/randomx/virtual_machine.hpp index 488994df6..cba79d724 100644 --- a/src/crypto/randomx/virtual_machine.hpp +++ b/src/crypto/randomx/virtual_machine.hpp @@ -33,26 +33,31 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "program.hpp" /* Global namespace for C binding */ -class randomx_vm { +class randomx_vm +{ public: virtual ~randomx_vm() = 0; - virtual void allocate() = 0; + virtual void setScratchpad(uint8_t *scratchpad) = 0; virtual void getFinalResult(void* out, size_t outSize) = 0; virtual void setDataset(randomx_dataset* dataset) { } virtual void setCache(randomx_cache* cache) { } virtual void initScratchpad(void* seed) = 0; virtual void run(void* seed) = 0; void resetRoundingMode(); + randomx::RegisterFile *getRegisterFile() { return ® } + const void* getScratchpad() { return scratchpad; } + const randomx::Program& getProgram() { return program; } + protected: void initialize(); alignas(64) randomx::Program program; @@ -69,15 +74,17 @@ protected: namespace randomx { - template - class VmBase : public randomx_vm { + template + class VmBase : public randomx_vm + { public: ~VmBase() override; - void allocate() override; + void setScratchpad(uint8_t *scratchpad) override; void initScratchpad(void* seed) override; void getFinalResult(void* out, size_t outSize) override; + protected: void generateProgram(void* seed); }; -} \ No newline at end of file +} diff --git a/src/crypto/randomx/vm_compiled.cpp b/src/crypto/randomx/vm_compiled.cpp index 7f621a335..4d14c7931 100644 --- a/src/crypto/randomx/vm_compiled.cpp +++ b/src/crypto/randomx/vm_compiled.cpp @@ -34,27 +34,25 @@ namespace randomx { static_assert(sizeof(MemoryRegisters) == 2 * sizeof(addr_t) + sizeof(uintptr_t), "Invalid alignment of struct randomx::MemoryRegisters"); static_assert(sizeof(RegisterFile) == 256, "Invalid alignment of struct randomx::RegisterFile"); - template - void CompiledVm::setDataset(randomx_dataset* dataset) { + template + void CompiledVm::setDataset(randomx_dataset* dataset) { datasetPtr = dataset; } - template - void CompiledVm::run(void* seed) { - VmBase::generateProgram(seed); + template + void CompiledVm::run(void* seed) { + VmBase::generateProgram(seed); randomx_vm::initialize(); compiler.generateProgram(program, config); mem.memory = datasetPtr->memory + datasetOffset; execute(); } - template - void CompiledVm::execute() { + template + void CompiledVm::execute() { compiler.getProgramFunc()(reg, mem, scratchpad, RandomX_CurrentConfig.ProgramIterations); } - template class CompiledVm, false>; - template class CompiledVm, true>; - template class CompiledVm; - template class CompiledVm; -} \ No newline at end of file + template class CompiledVm; + template class CompiledVm; +} diff --git a/src/crypto/randomx/vm_compiled.hpp b/src/crypto/randomx/vm_compiled.hpp index 856f00d8a..05b34b9c7 100644 --- a/src/crypto/randomx/vm_compiled.hpp +++ b/src/crypto/randomx/vm_compiled.hpp @@ -37,8 +37,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace randomx { - template - class CompiledVm : public VmBase { + template + class CompiledVm : public VmBase + { public: void* operator new(size_t size) { void* ptr = AlignedAllocator::allocMemory(size); @@ -46,27 +47,28 @@ namespace randomx { throw std::bad_alloc(); return ptr; } + void operator delete(void* ptr) { AlignedAllocator::freeMemory(ptr, sizeof(CompiledVm)); } + void setDataset(randomx_dataset* dataset) override; void run(void* seed) override; - using VmBase::mem; - using VmBase::program; - using VmBase::config; - using VmBase::reg; - using VmBase::scratchpad; - using VmBase::datasetPtr; - using VmBase::datasetOffset; + using VmBase::mem; + using VmBase::program; + using VmBase::config; + using VmBase::reg; + using VmBase::scratchpad; + using VmBase::datasetPtr; + using VmBase::datasetOffset; + protected: void execute(); JitCompiler compiler; }; - using CompiledVmDefault = CompiledVm, true>; - using CompiledVmHardAes = CompiledVm, false>; - using CompiledVmLargePage = CompiledVm; - using CompiledVmLargePageHardAes = CompiledVm; + using CompiledVmDefault = CompiledVm; + using CompiledVmHardAes = CompiledVm; } diff --git a/src/crypto/randomx/vm_compiled_light.cpp b/src/crypto/randomx/vm_compiled_light.cpp index c083f4aa9..6009216b3 100644 --- a/src/crypto/randomx/vm_compiled_light.cpp +++ b/src/crypto/randomx/vm_compiled_light.cpp @@ -32,23 +32,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace randomx { - template - void CompiledLightVm::setCache(randomx_cache* cache) { + template + void CompiledLightVm::setCache(randomx_cache* cache) { cachePtr = cache; mem.memory = cache->memory; compiler.generateSuperscalarHash(cache->programs, cache->reciprocalCache); } - template - void CompiledLightVm::run(void* seed) { - VmBase::generateProgram(seed); + template + void CompiledLightVm::run(void* seed) { + VmBase::generateProgram(seed); randomx_vm::initialize(); compiler.generateProgramLight(program, config, datasetOffset); - CompiledVm::execute(); + CompiledVm::execute(); } - template class CompiledLightVm, false>; - template class CompiledLightVm, true>; - template class CompiledLightVm; - template class CompiledLightVm; -} \ No newline at end of file + template class CompiledLightVm; + template class CompiledLightVm; +} diff --git a/src/crypto/randomx/vm_compiled_light.hpp b/src/crypto/randomx/vm_compiled_light.hpp index 6af82bbee..6cd3cb203 100644 --- a/src/crypto/randomx/vm_compiled_light.hpp +++ b/src/crypto/randomx/vm_compiled_light.hpp @@ -33,8 +33,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace randomx { - template - class CompiledLightVm : public CompiledVm { + template + class CompiledLightVm : public CompiledVm + { public: void* operator new(size_t size) { void* ptr = AlignedAllocator::allocMemory(size); @@ -42,23 +43,23 @@ namespace randomx { throw std::bad_alloc(); return ptr; } + void operator delete(void* ptr) { AlignedAllocator::freeMemory(ptr, sizeof(CompiledLightVm)); } + void setCache(randomx_cache* cache) override; void setDataset(randomx_dataset* dataset) override { } void run(void* seed) override; - using CompiledVm::mem; - using CompiledVm::compiler; - using CompiledVm::program; - using CompiledVm::config; - using CompiledVm::cachePtr; - using CompiledVm::datasetOffset; + using CompiledVm::mem; + using CompiledVm::compiler; + using CompiledVm::program; + using CompiledVm::config; + using CompiledVm::cachePtr; + using CompiledVm::datasetOffset; }; - using CompiledLightVmDefault = CompiledLightVm, true>; - using CompiledLightVmHardAes = CompiledLightVm, false>; - using CompiledLightVmLargePage = CompiledLightVm; - using CompiledLightVmLargePageHardAes = CompiledLightVm; -} \ No newline at end of file + using CompiledLightVmDefault = CompiledLightVm; + using CompiledLightVmHardAes = CompiledLightVm; +} diff --git a/src/crypto/randomx/vm_interpreted.cpp b/src/crypto/randomx/vm_interpreted.cpp index 236d3efe9..f4c1e05c9 100644 --- a/src/crypto/randomx/vm_interpreted.cpp +++ b/src/crypto/randomx/vm_interpreted.cpp @@ -33,21 +33,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace randomx { - template - void InterpretedVm::setDataset(randomx_dataset* dataset) { + template + void InterpretedVm::setDataset(randomx_dataset* dataset) { datasetPtr = dataset; mem.memory = dataset->memory; } - template - void InterpretedVm::run(void* seed) { - VmBase::generateProgram(seed); + template + void InterpretedVm::run(void* seed) { + VmBase::generateProgram(seed); randomx_vm::initialize(); execute(); } - template - void InterpretedVm::execute() { + template + void InterpretedVm::execute() { NativeRegisterFile nreg; @@ -106,20 +106,18 @@ namespace randomx { rx_store_vec_f128(®.e[i].lo, nreg.e[i]); } - template - void InterpretedVm::datasetRead(uint64_t address, int_reg_t(&r)[RegistersCount]) { + template + void InterpretedVm::datasetRead(uint64_t address, int_reg_t(&r)[RegistersCount]) { uint64_t* datasetLine = (uint64_t*)(mem.memory + address); for (int i = 0; i < RegistersCount; ++i) r[i] ^= datasetLine[i]; } - template - void InterpretedVm::datasetPrefetch(uint64_t address) { + template + void InterpretedVm::datasetPrefetch(uint64_t address) { rx_prefetch_nta(mem.memory + address); } - template class InterpretedVm, false>; - template class InterpretedVm, true>; - template class InterpretedVm; - template class InterpretedVm; -} \ No newline at end of file + template class InterpretedVm; + template class InterpretedVm; +} diff --git a/src/crypto/randomx/vm_interpreted.hpp b/src/crypto/randomx/vm_interpreted.hpp index 99c88852c..1dc9ab6dc 100644 --- a/src/crypto/randomx/vm_interpreted.hpp +++ b/src/crypto/randomx/vm_interpreted.hpp @@ -38,38 +38,41 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace randomx { - template - class InterpretedVm : public VmBase, public BytecodeMachine { + template + class InterpretedVm : public VmBase, public BytecodeMachine { public: - using VmBase::mem; - using VmBase::scratchpad; - using VmBase::program; - using VmBase::config; - using VmBase::reg; - using VmBase::datasetPtr; - using VmBase::datasetOffset; + using VmBase::mem; + using VmBase::scratchpad; + using VmBase::program; + using VmBase::config; + using VmBase::reg; + using VmBase::datasetPtr; + using VmBase::datasetOffset; + void* operator new(size_t size) { void* ptr = AlignedAllocator::allocMemory(size); if (ptr == nullptr) throw std::bad_alloc(); return ptr; } + void operator delete(void* ptr) { AlignedAllocator::freeMemory(ptr, sizeof(InterpretedVm)); } + void run(void* seed) override; void setDataset(randomx_dataset* dataset) override; + protected: virtual void datasetRead(uint64_t blockNumber, int_reg_t(&r)[RegistersCount]); virtual void datasetPrefetch(uint64_t blockNumber); + private: void execute(); InstructionByteCode bytecode[RANDOMX_PROGRAM_MAX_SIZE]; }; - using InterpretedVmDefault = InterpretedVm, true>; - using InterpretedVmHardAes = InterpretedVm, false>; - using InterpretedVmLargePage = InterpretedVm; - using InterpretedVmLargePageHardAes = InterpretedVm; -} \ No newline at end of file + using InterpretedVmDefault = InterpretedVm; + using InterpretedVmHardAes = InterpretedVm; +} diff --git a/src/crypto/randomx/vm_interpreted_light.cpp b/src/crypto/randomx/vm_interpreted_light.cpp index c54b32f64..9c97187b2 100644 --- a/src/crypto/randomx/vm_interpreted_light.cpp +++ b/src/crypto/randomx/vm_interpreted_light.cpp @@ -31,14 +31,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace randomx { - template - void InterpretedLightVm::setCache(randomx_cache* cache) { + template + void InterpretedLightVm::setCache(randomx_cache* cache) { cachePtr = cache; mem.memory = cache->memory; } - template - void InterpretedLightVm::datasetRead(uint64_t address, int_reg_t(&r)[8]) { + template + void InterpretedLightVm::datasetRead(uint64_t address, int_reg_t(&r)[8]) { uint32_t itemNumber = address / CacheLineSize; int_reg_t rl[8]; @@ -48,8 +48,6 @@ namespace randomx { r[q] ^= rl[q]; } - template class InterpretedLightVm, false>; - template class InterpretedLightVm, true>; - template class InterpretedLightVm; - template class InterpretedLightVm; + template class InterpretedLightVm; + template class InterpretedLightVm; } diff --git a/src/crypto/randomx/vm_interpreted_light.hpp b/src/crypto/randomx/vm_interpreted_light.hpp index 02d678f6e..1a35c5801 100644 --- a/src/crypto/randomx/vm_interpreted_light.hpp +++ b/src/crypto/randomx/vm_interpreted_light.hpp @@ -33,29 +33,31 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace randomx { - template - class InterpretedLightVm : public InterpretedVm { + template + class InterpretedLightVm : public InterpretedVm { public: - using VmBase::mem; - using VmBase::cachePtr; + using VmBase::mem; + using VmBase::cachePtr; + void* operator new(size_t size) { void* ptr = AlignedAllocator::allocMemory(size); if (ptr == nullptr) throw std::bad_alloc(); return ptr; } + void operator delete(void* ptr) { AlignedAllocator::freeMemory(ptr, sizeof(InterpretedLightVm)); } + void setDataset(randomx_dataset* dataset) override { } void setCache(randomx_cache* cache) override; + protected: void datasetRead(uint64_t address, int_reg_t(&r)[8]) override; void datasetPrefetch(uint64_t address) override { } }; - using InterpretedLightVmDefault = InterpretedLightVm, true>; - using InterpretedLightVmHardAes = InterpretedLightVm, false>; - using InterpretedLightVmLargePage = InterpretedLightVm; - using InterpretedLightVmLargePageHardAes = InterpretedLightVm; + using InterpretedLightVmDefault = InterpretedLightVm; + using InterpretedLightVmHardAes = InterpretedLightVm; } diff --git a/src/crypto/rx/RxVm.cpp b/src/crypto/rx/RxVm.cpp index b02f708e5..6426443a4 100644 --- a/src/crypto/rx/RxVm.cpp +++ b/src/crypto/rx/RxVm.cpp @@ -31,12 +31,8 @@ #include "crypto/rx/RxVm.h" -xmrig::RxVm::RxVm(RxDataset *dataset, bool hugePages, bool softAes) +xmrig::RxVm::RxVm(RxDataset *dataset, uint8_t *scratchpad, bool softAes) { - if (hugePages) { - m_flags |= RANDOMX_FLAG_LARGE_PAGES; - } - if (!softAes) { m_flags |= RANDOMX_FLAG_HARD_AES; } @@ -49,17 +45,7 @@ xmrig::RxVm::RxVm(RxDataset *dataset, bool hugePages, bool softAes) m_flags |= RANDOMX_FLAG_JIT; } - m_vm = randomx_create_vm(static_cast(m_flags), dataset->cache()->get(), dataset->get()); - - if (!m_vm) { - m_flags &= ~RANDOMX_FLAG_LARGE_PAGES; - m_vm = randomx_create_vm(static_cast(m_flags), dataset->cache()->get(), dataset->get()); - } - - if (!m_vm) { - m_flags &= ~RANDOMX_FLAG_HARD_AES; - m_vm = randomx_create_vm(static_cast(m_flags), dataset->cache()->get(), dataset->get()); - } + m_vm = randomx_create_vm(static_cast(m_flags), dataset->cache()->get(), dataset->get(), scratchpad); } diff --git a/src/crypto/rx/RxVm.h b/src/crypto/rx/RxVm.h index 90af8187e..d7e617e4d 100644 --- a/src/crypto/rx/RxVm.h +++ b/src/crypto/rx/RxVm.h @@ -44,7 +44,7 @@ class RxDataset; class RxVm { public: - RxVm(RxDataset *dataset, bool hugePages, bool softAes); + RxVm(RxDataset *dataset, uint8_t *scratchpad, bool softAes); ~RxVm(); inline randomx_vm *get() const { return m_vm; } diff --git a/src/workers/WorkersLegacy.cpp b/src/workers/WorkersLegacy.cpp index 0db0a3cff..4d6f9de9a 100644 --- a/src/workers/WorkersLegacy.cpp +++ b/src/workers/WorkersLegacy.cpp @@ -67,24 +67,24 @@ xmrig::Controller *WorkersLegacy::m_controller = nullptr; //} -size_t WorkersLegacy::hugePages() -{ - uv_mutex_lock(&m_mutex); - const size_t hugePages = m_status.hugePages; - uv_mutex_unlock(&m_mutex); +//size_t WorkersLegacy::hugePages() +//{ +// uv_mutex_lock(&m_mutex); +// const size_t hugePages = m_status.hugePages; +// uv_mutex_unlock(&m_mutex); - return hugePages; -} +// return hugePages; +//} -size_t WorkersLegacy::threads() -{ - uv_mutex_lock(&m_mutex); - const size_t threads = m_status.threads; - uv_mutex_unlock(&m_mutex); +//size_t WorkersLegacy::threads() +//{ +// uv_mutex_lock(&m_mutex); +// const size_t threads = m_status.threads; +// uv_mutex_unlock(&m_mutex); - return threads; -} +// return threads; +//} //void Workers::pause() @@ -186,24 +186,24 @@ void WorkersLegacy::start(xmrig::Controller *controller) //} -#ifdef XMRIG_FEATURE_API -void WorkersLegacy::threadsSummary(rapidjson::Document &doc) -{ - uv_mutex_lock(&m_mutex); - const uint64_t pages[2] = { m_status.hugePages, m_status.pages }; - const uint64_t memory = m_status.ways * xmrig::CnAlgo<>::memory(m_status.algo); - uv_mutex_unlock(&m_mutex); +//#ifdef XMRIG_FEATURE_API +//void WorkersLegacy::threadsSummary(rapidjson::Document &doc) +//{ +// uv_mutex_lock(&m_mutex); +// const uint64_t pages[2] = { m_status.hugePages, m_status.pages }; +// const uint64_t memory = m_status.ways * xmrig::CnAlgo<>::memory(m_status.algo); +// uv_mutex_unlock(&m_mutex); - auto &allocator = doc.GetAllocator(); +// auto &allocator = doc.GetAllocator(); - rapidjson::Value hugepages(rapidjson::kArrayType); - hugepages.PushBack(pages[0], allocator); - hugepages.PushBack(pages[1], allocator); +// rapidjson::Value hugepages(rapidjson::kArrayType); +// hugepages.PushBack(pages[0], allocator); +// hugepages.PushBack(pages[1], allocator); - doc.AddMember("hugepages", hugepages, allocator); - doc.AddMember("memory", memory, allocator); -} -#endif +// doc.AddMember("hugepages", hugepages, allocator); +// doc.AddMember("memory", memory, allocator); +//} +//#endif //void WorkersLegacy::onTick(uv_timer_t *) diff --git a/src/workers/WorkersLegacy.h b/src/workers/WorkersLegacy.h index be9e417af..d8ab1e59d 100644 --- a/src/workers/WorkersLegacy.h +++ b/src/workers/WorkersLegacy.h @@ -55,8 +55,8 @@ namespace xmrig { class WorkersLegacy { public: - static size_t hugePages(); - static size_t threads(); +// static size_t hugePages(); +// static size_t threads(); // static void pause(); // static void printHashrate(bool detail); // static void setEnabled(bool enabled); @@ -68,9 +68,9 @@ public: // static inline bool isEnabled() { return m_enabled; } // static inline Hashrate *hashrate() { return m_hashrate; } -# ifdef XMRIG_FEATURE_API - static void threadsSummary(rapidjson::Document &doc); -# endif +//# ifdef XMRIG_FEATURE_API +// static void threadsSummary(rapidjson::Document &doc); +//# endif private: // static void onReady(void *arg);