From 207dae418d533d94961c9b7f413613c69a10058e Mon Sep 17 00:00:00 2001 From: XMRig Date: Fri, 4 Oct 2019 18:43:03 +0700 Subject: [PATCH] Added RxNUMAStorage stub. --- cmake/randomx.cmake | 5 + src/backend/cpu/platform/HwlocCpuInfo.cpp | 14 ++ src/backend/cpu/platform/HwlocCpuInfo.h | 7 +- src/crypto/rx/Rx.cpp | 19 ++- src/crypto/rx/RxBasicStorage.h | 6 +- src/crypto/rx/RxNUMAStorage.cpp | 166 ++++++++++++++++++++++ src/crypto/rx/RxNUMAStorage.h | 66 +++++++++ 7 files changed, 275 insertions(+), 8 deletions(-) create mode 100644 src/crypto/rx/RxNUMAStorage.cpp create mode 100644 src/crypto/rx/RxNUMAStorage.h diff --git a/cmake/randomx.cmake b/cmake/randomx.cmake index 40727e93f..27b9d9f60 100644 --- a/cmake/randomx.cmake +++ b/cmake/randomx.cmake @@ -68,8 +68,13 @@ if (WITH_RANDOMX) endif() if (WITH_HWLOC) + list(APPEND SOURCES_CRYPTO + src/crypto/rx/RxNUMAStorage.h + ) + list(APPEND SOURCES_CRYPTO src/crypto/rx/RxConfig_hwloc.cpp + src/crypto/rx/RxNUMAStorage.cpp ) else() list(APPEND SOURCES_CRYPTO diff --git a/src/backend/cpu/platform/HwlocCpuInfo.cpp b/src/backend/cpu/platform/HwlocCpuInfo.cpp index dfb946863..3983e8b02 100644 --- a/src/backend/cpu/platform/HwlocCpuInfo.cpp +++ b/src/backend/cpu/platform/HwlocCpuInfo.cpp @@ -200,6 +200,20 @@ xmrig::HwlocCpuInfo::~HwlocCpuInfo() } +bool xmrig::HwlocCpuInfo::membind(hwloc_const_bitmap_t nodeset) +{ + if (!hwloc_topology_get_support(m_topology)->membind->set_thisthread_membind) { + return false; + } + +# if HWLOC_API_VERSION >= 0x20000 + return hwloc_set_membind(m_topology, nodeset, HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_THREAD | HWLOC_MEMBIND_BYNODESET) >= 0; +# else + return hwloc_set_membind_nodeset(m_topology, nodeset, HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_THREAD) >= 0; +# endif +} + + xmrig::CpuThreads xmrig::HwlocCpuInfo::threads(const Algorithm &algorithm, uint32_t limit) const { if (L2() == 0 && L3() == 0) { diff --git a/src/backend/cpu/platform/HwlocCpuInfo.h b/src/backend/cpu/platform/HwlocCpuInfo.h index b796afb22..c22291e85 100644 --- a/src/backend/cpu/platform/HwlocCpuInfo.h +++ b/src/backend/cpu/platform/HwlocCpuInfo.h @@ -30,8 +30,9 @@ #include "base/tools/Object.h" -using hwloc_obj_t = struct hwloc_obj *; -using hwloc_topology_t = struct hwloc_topology *; +using hwloc_const_bitmap_t = const struct hwloc_bitmap_s *; +using hwloc_obj_t = struct hwloc_obj *; +using hwloc_topology_t = struct hwloc_topology *; namespace xmrig { @@ -56,6 +57,8 @@ public: inline const std::vector &nodeset() const { return m_nodeset; } inline hwloc_topology_t topology() const { return m_topology; } + bool membind(hwloc_const_bitmap_t nodeset); + protected: CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const override; diff --git a/src/crypto/rx/Rx.cpp b/src/crypto/rx/Rx.cpp index 3e8d06e07..708a9559c 100644 --- a/src/crypto/rx/Rx.cpp +++ b/src/crypto/rx/Rx.cpp @@ -46,6 +46,11 @@ #include "crypto/rx/RxSeed.h" +#ifdef XMRIG_FEATURE_HWLOC +# include "crypto/rx/RxNUMAStorage.h" +#endif + + #include #include #include @@ -94,10 +99,18 @@ public: inline void asyncSend() { --m_pending; if (pending() == 0) { uv_async_send(m_async); } } - inline IRxStorage *storage() + inline IRxStorage *storage(const std::vector &nodeset) { if (!m_storage) { - m_storage = new RxBasicStorage(); +# ifdef XMRIG_FEATURE_HWLOC + if (!nodeset.empty()) { + m_storage = new RxNUMAStorage(nodeset); + } + else +# endif + { + m_storage = new RxBasicStorage(); + } } return m_storage; @@ -116,7 +129,7 @@ public: Buffer::toHex(seed.data().data(), 8).data() ); - d_ptr->storage()->init(seed, threads, hugePages); + d_ptr->storage(nodeset)->init(seed, threads, hugePages); d_ptr->asyncSend(); } diff --git a/src/crypto/rx/RxBasicStorage.h b/src/crypto/rx/RxBasicStorage.h index d6dad10dc..63eba1d95 100644 --- a/src/crypto/rx/RxBasicStorage.h +++ b/src/crypto/rx/RxBasicStorage.h @@ -24,8 +24,8 @@ * along with this program. If not, see . */ -#ifndef XMRIG_RX_VM_H -#define XMRIG_RX_VM_H +#ifndef XMRIG_RX_BASICSTORAGE_H +#define XMRIG_RX_BASICSTORAGE_H #include "backend/common/interfaces/IRxStorage.h" @@ -60,4 +60,4 @@ private: } /* namespace xmrig */ -#endif /* XMRIG_RX_VM_H */ +#endif /* XMRIG_RX_BASICSTORAGE_H */ diff --git a/src/crypto/rx/RxNUMAStorage.cpp b/src/crypto/rx/RxNUMAStorage.cpp new file mode 100644 index 000000000..3d5b999a9 --- /dev/null +++ b/src/crypto/rx/RxNUMAStorage.cpp @@ -0,0 +1,166 @@ +/* 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 tevador + * 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 "crypto/rx/RxNUMAStorage.h" +#include "backend/common/Tags.h" +#include "base/io/log/Log.h" +#include "base/tools/Chrono.h" +#include "crypto/rx/RxAlgo.h" +#include "crypto/rx/RxCache.h" +#include "crypto/rx/RxDataset.h" +#include "crypto/rx/RxSeed.h" + + +#include + + +namespace xmrig { + + +constexpr size_t oneMiB = 1024 * 1024; + + +class RxNUMAStoragePrivate +{ +public: + inline bool isReady(const Job &job) const { return m_ready && m_seed == job; } + inline RxDataset *dataset() const { return m_dataset; } + + + inline void setSeed(const RxSeed &seed) + { + m_ready = false; + + if (m_seed.algorithm() != seed.algorithm()) { + RxAlgo::apply(seed.algorithm()); + } + + m_seed = seed; + } + + + inline void createDataset(bool hugePages) + { + const uint64_t ts = Chrono::steadyMSecs(); + + m_dataset = new RxDataset(hugePages, true); + printAllocStatus(ts); + } + + + inline void initDataset(uint32_t threads, uint64_t ts) + { + m_dataset->init(m_seed.data(), threads); + + LOG_INFO("%s" GREEN_BOLD("dataset ready") BLACK_BOLD(" (%" PRIu64 " ms)"), rx_tag(), Chrono::steadyMSecs() - ts); + + m_ready = true; + } + + +private: + void printAllocStatus(uint64_t ts) + { + if (m_dataset->get() != nullptr) { + const auto pages = m_dataset->hugePages(); + const double percent = pages.first == 0 ? 0.0 : static_cast(pages.first) / pages.second * 100.0; + + LOG_INFO("%s" GREEN_BOLD("allocated") CYAN_BOLD(" %zu MB") BLACK_BOLD(" (%zu+%zu)") " huge pages %s%u/%u %1.0f%%" CLEAR " %sJIT" BLACK_BOLD(" (%" PRIu64 " ms)"), + rx_tag(), + (RxDataset::maxSize() + RxCache::maxSize()) / oneMiB, + RxDataset::maxSize() / oneMiB, + RxCache::maxSize() / oneMiB, + (pages.first == pages.second ? GREEN_BOLD_S : (pages.first == 0 ? RED_BOLD_S : YELLOW_BOLD_S)), + pages.first, + pages.second, + percent, + m_dataset->cache()->isJIT() ? GREEN_BOLD_S "+" : RED_BOLD_S "-", + Chrono::steadyMSecs() - ts + ); + } + else { + LOG_WARN(CLEAR "%s" YELLOW_BOLD_S "failed to allocate RandomX dataset, switching to slow mode" BLACK_BOLD(" (%" PRIu64 " ms)"), rx_tag(), Chrono::steadyMSecs() - ts); + } + } + + + bool m_ready = false; + RxDataset *m_dataset = nullptr; + RxSeed m_seed; + std::map m_datasets; + std::vector m_nodeset; +}; + + +} // namespace xmrig + + +xmrig::RxNUMAStorage::RxNUMAStorage(const std::vector &nodeset) : + d_ptr(new RxNUMAStoragePrivate()) +{ + LOG_WARN(">>>>>> %zu", nodeset.size()); // FIXME +} + + +xmrig::RxNUMAStorage::~RxNUMAStorage() +{ + delete d_ptr; +} + + +xmrig::RxDataset *xmrig::RxNUMAStorage::dataset(const Job &job, uint32_t) const +{ + if (!d_ptr->isReady(job)) { + return nullptr; + } + + return d_ptr->dataset(); +} + + +std::pair xmrig::RxNUMAStorage::hugePages() const +{ + if (!d_ptr->dataset()) { + return { 0u, 0u }; + } + + return d_ptr->dataset()->hugePages(); +} + + +void xmrig::RxNUMAStorage::init(const RxSeed &seed, uint32_t threads, bool hugePages) +{ + const uint64_t ts = Chrono::steadyMSecs(); + + d_ptr->setSeed(seed); + + if (!d_ptr->dataset()) { + d_ptr->createDataset(hugePages); + } + + d_ptr->initDataset(threads, ts); +} diff --git a/src/crypto/rx/RxNUMAStorage.h b/src/crypto/rx/RxNUMAStorage.h new file mode 100644 index 000000000..3afdd81d9 --- /dev/null +++ b/src/crypto/rx/RxNUMAStorage.h @@ -0,0 +1,66 @@ +/* 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 tevador + * 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_RX_NUMASTORAGE_H +#define XMRIG_RX_NUMASTORAGE_H + + +#include "backend/common/interfaces/IRxStorage.h" +#include "base/tools/Object.h" + + +#include + + +namespace xmrig +{ + + +class RxNUMAStoragePrivate; + + +class RxNUMAStorage : public IRxStorage +{ +public: + XMRIG_DISABLE_COPY_MOVE(RxNUMAStorage); + + RxNUMAStorage(const std::vector &nodeset); + ~RxNUMAStorage() override; + +protected: + RxDataset *dataset(const Job &job, uint32_t nodeId) const override; + std::pair hugePages() const override; + void init(const RxSeed &seed, uint32_t threads, bool hugePages) override; + +private: + RxNUMAStoragePrivate *d_ptr; +}; + + +} /* namespace xmrig */ + + +#endif /* XMRIG_RX_NUMASTORAGE_H */