diff --git a/CHANGELOG.md b/CHANGELOG.md index e6aaeea6..7dd9cb25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# v4.2.1-beta +- [#1150](https://github.com/xmrig/xmrig/issues/1150) Fixed build on FreeBSD. +- [#1175](https://github.com/xmrig/xmrig/issues/1175) Fixed support for systems where total count of NUMA nodes not equal usable nodes count. +- [#1199](https://github.com/xmrig/xmrig/issues/1199) Fixed excessive memory allocation for OpenCL threads with low intensity. +- [#1212](https://github.com/xmrig/xmrig/issues/1212) Fixed low RandomX performance after fast algorithm switching. + # v4.2.0-beta - [#1202](https://github.com/xmrig/xmrig/issues/1202) Fixed algorithm verification in donate strategy. - Added per pool option `coin` with single possible value `monero` for pools without algorithm negotiation, for upcoming Monero fork. @@ -23,6 +29,10 @@ - [#268](https://github.com/xmrig/xmrig-amd/pull/268) [#270](https://github.com/xmrig/xmrig-amd/pull/270) [#271](https://github.com/xmrig/xmrig-amd/pull/271) [#273](https://github.com/xmrig/xmrig-amd/pull/273) [#274](https://github.com/xmrig/xmrig-amd/pull/274) [#1171](https://github.com/xmrig/xmrig/pull/1171) Added RandomX support for OpenCL, thanks [@SChernykh](https://github.com/SChernykh). - Algorithm `cn/wow` removed, as no longer alive. +# v3.2.0 +- Added per pool option `coin` with single possible value `monero` for pools without algorithm negotiation, for upcoming Monero fork. +- [#1183](https://github.com/xmrig/xmrig/issues/1183) Fixed compatibility with systemd. + # v3.1.3 - [#1180](https://github.com/xmrig/xmrig/issues/1180) Fixed possible duplicated shares after algorithm switching. - Fixed wrong config file permissions after write (only gcc builds on recent Windows 10 affected). diff --git a/README.md b/README.md index ee499d47..be1ed702 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # XMRig +**:warning: [Monero will change PoW algorithm to RandomX on November 30.](https://github.com/xmrig/xmrig/issues/1204)** + [![Github All Releases](https://img.shields.io/github/downloads/xmrig/xmrig/total.svg)](https://github.com/xmrig/xmrig/releases) [![GitHub release](https://img.shields.io/github/release/xmrig/xmrig/all.svg)](https://github.com/xmrig/xmrig/releases) [![GitHub Release Date](https://img.shields.io/github/release-date-pre/xmrig/xmrig.svg)](https://github.com/xmrig/xmrig/releases) @@ -26,7 +28,7 @@ XMRig is a high performance RandomX and CryptoNight CPU miner, with official sup * Clone with `git clone https://github.com/xmrig/xmrig.git` :hammer: [Build instructions](https://github.com/xmrig/xmrig/wiki/Build). ## Usage -Preferend way to configure miner is [JSON config file](src/config.json) as more flexible and human frendly, command line interface not cover all features, for example mining profiles for different algorithms. Most impotant options can be changed in runtime without miner restart by editing config or via API. +The preferred way to configure the miner is the [JSON config file](src/config.json) as it is more flexible and human friendly. The command line interface does not cover all features, such as mining profiles for different algorithms. Important options can be changed during runtime without miner restart by editing the config file or executing API calls. ### Options ``` diff --git a/doc/ALGORITHMS.md b/doc/ALGORITHMS.md index aff8b3bf..c31ad6c7 100644 --- a/doc/ALGORITHMS.md +++ b/doc/ALGORITHMS.md @@ -1,34 +1,20 @@ # Algorithms -Since version 3 mining [algorithm](#algorithm-names) should specified for each pool separately (`algo` option), earlier versions was use one global `algo` option and per pool `variant` option (this option was removed in v3). If your pool support [mining algorithm negotiation](https://github.com/xmrig/xmrig-proxy/issues/168) you may not specify this option at all. - -#### Example -```json -{ - "pools": [ - { - "url": "...", - "algo": "cn/r", - ... - } - ], - ... -} -``` +Algorithm can be defined in 3 ways: -#### Pools with mining algorithm negotiation support. +1. By pool, using algorithm negotiation, in this case no need specify algorithm on miner side. +2. Per pool `coin` option, currently only usable value for this option is `monero`. +3. Per pool `algo` option. - * [www.hashvault.pro](https://www.hashvault.pro/) - * [moneroocean.stream](https://moneroocean.stream) - - ## Algorithm names +Option `coin` useful for pools without algorithm negotiation support or daemon to allow automatically switch algorithm in next hard fork. + +## Algorithm names | Name | Memory | Version | Notes | |------|--------|---------|-------| +| `rx/0` | 2 MB | 3.2.0+ | RandomX (Monero). | | `argon2/chukwa` | 512 KB | 3.1.0+ | Argon2id (Chukwa). | | `argon2/wrkz` | 256 KB | 3.1.0+ | Argon2id (WRKZ) | -| `rx/test` | 2 MB | 3.0.0+ | RandomX (reference configuration). | -| `rx/0` | 2 MB | 3.0.0+ | RandomX (reference configuration), reserved for future use. | | `rx/wow` | 1 MB | 3.0.0+ | RandomWOW. | | `rx/loki` | 2 MB | 3.0.0+ | RandomXL. | | `cn/fast` | 2 MB | 3.0.0+ | CryptoNight variant 1 with half iterations. | @@ -50,3 +36,21 @@ Since version 3 mining [algorithm](#algorithm-names) should specified for each p | `cn-lite/1` | 1 MB | 2.5.0+ | CryptoNight-Lite variant 1. | | `cn-lite/0` | 1 MB | 0.8.0+ | CryptoNight-Lite variant 0. | | `cn/0` | 2 MB | 0.5.0+ | CryptoNight (original). | + +## Migration to v3 +Since version 3 mining [algorithm](#algorithm-names) should specified for each pool separately (`algo` option), earlier versions was use one global `algo` option and per pool `variant` option (this option was removed in v3). If your pool support [mining algorithm negotiation](https://github.com/xmrig/xmrig-proxy/issues/168) you may not specify this option at all. + +#### Example +```json +{ + "pools": [ + { + "url": "...", + "algo": "cn/r", + "coin": null + ... + } + ], + ... +} +``` diff --git a/src/3rdparty/argon2/CMakeLists.txt b/src/3rdparty/argon2/CMakeLists.txt index f77835f3..0217382a 100644 --- a/src/3rdparty/argon2/CMakeLists.txt +++ b/src/3rdparty/argon2/CMakeLists.txt @@ -22,7 +22,7 @@ set(ARGON2_X86_64_SOURCES arch/x86_64/lib/argon2-arch.c arch/x86_64/lib/cpu-flag if (CMAKE_C_COMPILER_ID MATCHES MSVC) function(add_feature_impl FEATURE MSVC_FLAG DEF) add_library(argon2-${FEATURE} STATIC arch/x86_64/lib/argon2-${FEATURE}.c) - target_include_directories(argon2-${FEATURE} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include) + target_include_directories(argon2-${FEATURE} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../) target_include_directories(argon2-${FEATURE} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/lib) set_target_properties(argon2-${FEATURE} PROPERTIES POSITION_INDEPENDENT_CODE True) @@ -38,7 +38,7 @@ if (CMAKE_C_COMPILER_ID MATCHES MSVC) elseif (NOT XMRIG_ARM AND CMAKE_SIZEOF_VOID_P EQUAL 8) function(add_feature_impl FEATURE GCC_FLAG DEF) add_library(argon2-${FEATURE} STATIC arch/x86_64/lib/argon2-${FEATURE}.c) - target_include_directories(argon2-${FEATURE} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include) + target_include_directories(argon2-${FEATURE} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../) target_include_directories(argon2-${FEATURE} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/lib) set_target_properties(argon2-${FEATURE} PROPERTIES POSITION_INDEPENDENT_CODE True) @@ -84,5 +84,5 @@ endif() add_library(argon2 STATIC ${ARGON2_SOURCES}) target_link_libraries(argon2 ${ARGON2_LIBS}) -target_include_directories(argon2 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include) +target_include_directories(argon2 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../) target_include_directories(argon2 PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/lib) diff --git a/src/3rdparty/argon2/lib/argon2.c b/src/3rdparty/argon2/lib/argon2.c index d4d038a9..b2eafd2f 100644 --- a/src/3rdparty/argon2/lib/argon2.c +++ b/src/3rdparty/argon2/lib/argon2.c @@ -15,7 +15,7 @@ #include #include -#include "argon2.h" +#include "3rdparty/argon2.h" #include "encoding.h" #include "core.h" diff --git a/src/3rdparty/argon2/lib/core.h b/src/3rdparty/argon2/lib/core.h index 5c67fa36..8a3227a9 100644 --- a/src/3rdparty/argon2/lib/core.h +++ b/src/3rdparty/argon2/lib/core.h @@ -14,7 +14,7 @@ #ifndef ARGON2_CORE_H #define ARGON2_CORE_H -#include "argon2.h" +#include "3rdparty/argon2.h" #if defined(_MSC_VER) #define ALIGN(n) __declspec(align(16)) diff --git a/src/3rdparty/argon2/lib/encoding.h b/src/3rdparty/argon2/lib/encoding.h index e7834e4f..742fe888 100644 --- a/src/3rdparty/argon2/lib/encoding.h +++ b/src/3rdparty/argon2/lib/encoding.h @@ -1,6 +1,6 @@ #ifndef ENCODING_H #define ENCODING_H -#include "argon2.h" +#include "3rdparty/argon2.h" #define ARGON2_MAX_DECODED_LANES UINT32_C(255) #define ARGON2_MIN_DECODED_SALT_LEN UINT32_C(8) diff --git a/src/3rdparty/argon2/lib/impl-select.c b/src/3rdparty/argon2/lib/impl-select.c index d618010c..965b639e 100644 --- a/src/3rdparty/argon2/lib/impl-select.c +++ b/src/3rdparty/argon2/lib/impl-select.c @@ -3,7 +3,7 @@ #include "impl-select.h" -#include "argon2.h" +#include "3rdparty/argon2.h" #define BENCH_SAMPLES 1024 #define BENCH_MEM_BLOCKS 512 diff --git a/src/backend/common/Workers.cpp b/src/backend/common/Workers.cpp index 2c90dfe0..9fb6859e 100644 --- a/src/backend/common/Workers.cpp +++ b/src/backend/common/Workers.cpp @@ -100,6 +100,7 @@ void xmrig::Workers::start(const std::vector &data) } d_ptr->hashrate = new Hashrate(m_workers.size()); + Nonce::touch(T::backend()); for (Thread *worker : m_workers) { worker->start(Workers::onReady); diff --git a/src/backend/cpu/platform/HwlocCpuInfo.cpp b/src/backend/cpu/platform/HwlocCpuInfo.cpp index e87faf2d..c9a45e1d 100644 --- a/src/backend/cpu/platform/HwlocCpuInfo.cpp +++ b/src/backend/cpu/platform/HwlocCpuInfo.cpp @@ -177,7 +177,7 @@ xmrig::HwlocCpuInfo::HwlocCpuInfo() m_threads = countByType(m_topology, HWLOC_OBJ_PU); m_cores = countByType(m_topology, HWLOC_OBJ_CORE); - m_nodes = std::max(countByType(m_topology, HWLOC_OBJ_NUMANODE), 1); + m_nodes = std::max(hwloc_bitmap_weight(hwloc_topology_get_complete_nodeset(m_topology)), 1); m_packages = countByType(m_topology, HWLOC_OBJ_PACKAGE); if (m_nodes > 1) { diff --git a/src/backend/opencl/OclBackend.cpp b/src/backend/opencl/OclBackend.cpp index 9b226811..5b078006 100644 --- a/src/backend/opencl/OclBackend.cpp +++ b/src/backend/opencl/OclBackend.cpp @@ -35,6 +35,7 @@ #include "backend/opencl/OclConfig.h" #include "backend/opencl/OclLaunchData.h" #include "backend/opencl/OclWorker.h" +#include "backend/opencl/runners/tools/OclSharedState.h" #include "backend/opencl/wrappers/OclContext.h" #include "backend/opencl/wrappers/OclLib.h" #include "base/io/log/Log.h" @@ -164,7 +165,7 @@ public: } - inline void start() + inline void start(const Job &job) { LOG_INFO("%s use profile " BLUE_BG(WHITE_BOLD_S " %s ") WHITE_BOLD_S " (" CYAN_BOLD("%zu") WHITE_BOLD(" threads)") " scratchpad " CYAN_BOLD("%zu KB"), tag, @@ -194,6 +195,8 @@ public: i++; } + OclSharedState::start(threads, job); + status.start(threads.size()); workers.start(threads); } @@ -329,7 +332,7 @@ void xmrig::OclBackend::setJob(const Job &job) return stop(); } - if (!d_ptr->context.init(d_ptr->devices, threads, job)) { + if (!d_ptr->context.init(d_ptr->devices, threads)) { LOG_WARN("%s " RED_BOLD("disabled") YELLOW(" (OpenCL context unavailable)"), tag); return stop(); @@ -338,7 +341,7 @@ void xmrig::OclBackend::setJob(const Job &job) stop(); d_ptr->threads = std::move(threads); - d_ptr->start(); + d_ptr->start(job); } @@ -371,6 +374,8 @@ void xmrig::OclBackend::stop() d_ptr->workers.stop(); d_ptr->threads.clear(); + OclSharedState::release(); + LOG_INFO("%s" YELLOW(" stopped") BLACK_BOLD(" (%" PRIu64 " ms)"), tag, Chrono::steadyMSecs() - ts); } diff --git a/src/backend/opencl/OclConfig.cpp b/src/backend/opencl/OclConfig.cpp index 7424dba7..bdefcaae 100644 --- a/src/backend/opencl/OclConfig.cpp +++ b/src/backend/opencl/OclConfig.cpp @@ -193,32 +193,13 @@ std::vector xmrig::OclConfig::get(const Miner *miner, cons continue; } -# ifdef XMRIG_ALGO_RANDOMX - auto dataset = algorithm.family() == Algorithm::RANDOM_X ? std::make_shared() : nullptr; -# endif - if (thread.threads().size() > 1) { - auto interleave = std::make_shared(thread.threads().size()); - for (int64_t affinity : thread.threads()) { - OclLaunchData data(miner, algorithm, *this, platform, thread, devices[thread.index()], affinity); - data.interleave = interleave; - -# ifdef XMRIG_ALGO_RANDOMX - data.dataset = dataset; -# endif - - out.emplace_back(std::move(data)); + out.emplace_back(miner, algorithm, *this, platform, thread, devices[thread.index()], affinity); } } else { - OclLaunchData data(miner, algorithm, *this, platform, thread, devices[thread.index()], thread.threads().front()); - -# ifdef XMRIG_ALGO_RANDOMX - data.dataset = dataset; -# endif - - out.emplace_back(std::move(data)); + out.emplace_back(miner, algorithm, *this, platform, thread, devices[thread.index()], thread.threads().front()); } } diff --git a/src/backend/opencl/OclLaunchData.h b/src/backend/opencl/OclLaunchData.h index ab4ca09b..644023be 100644 --- a/src/backend/opencl/OclLaunchData.h +++ b/src/backend/opencl/OclLaunchData.h @@ -27,19 +27,14 @@ #define XMRIG_OCLLAUNCHDATA_H -#include "backend/opencl/OclInterleave.h" #include "backend/opencl/OclThread.h" +#include "backend/opencl/runners/tools/OclSharedData.h" #include "backend/opencl/wrappers/OclDevice.h" #include "backend/opencl/wrappers/OclPlatform.h" #include "crypto/common/Algorithm.h" #include "crypto/common/Nonce.h" -#ifdef XMRIG_ALGO_RANDOMX -# include "backend/opencl/runners/tools/OclRxDataset.h" -#endif - - using cl_context = struct _cl_context *; @@ -72,11 +67,6 @@ public: const OclDevice device; const OclPlatform platform; const OclThread thread; - OclInterleavePtr interleave; - -# ifdef XMRIG_ALGO_RANDOMX - OclRxDatasetPtr dataset; -# endif }; diff --git a/src/backend/opencl/OclWorker.cpp b/src/backend/opencl/OclWorker.cpp index b4132e3d..f79bc59b 100644 --- a/src/backend/opencl/OclWorker.cpp +++ b/src/backend/opencl/OclWorker.cpp @@ -28,6 +28,8 @@ #include "backend/common/Tags.h" #include "backend/opencl/runners/OclCnRunner.h" +#include "backend/opencl/runners/tools/OclSharedData.h" +#include "backend/opencl/runners/tools/OclSharedState.h" #include "base/io/log/Log.h" #include "base/tools/Chrono.h" #include "core/Miner.h" @@ -75,7 +77,7 @@ xmrig::OclWorker::OclWorker(size_t id, const OclLaunchData &data) : m_algorithm(data.algorithm), m_miner(data.miner), m_intensity(data.thread.intensity()), - m_interleave(data.interleave) + m_sharedData(OclSharedState::get(data.device.index())) { switch (m_algorithm.family()) { case Algorithm::RANDOM_X: @@ -149,9 +151,7 @@ void xmrig::OclWorker::start() while (Nonce::sequence(Nonce::OPENCL) > 0) { if (!isReady()) { - if (m_interleave) { - m_interleave->setResumeCounter(0); - } + m_sharedData.setResumeCounter(0); do { std::this_thread::sleep_for(std::chrono::milliseconds(200)); @@ -162,9 +162,7 @@ void xmrig::OclWorker::start() break; } - if (m_interleave) { - m_interleave->resumeDelay(m_id); - } + m_sharedData.resumeDelay(m_id); if (!consumeJob()) { return; @@ -172,9 +170,7 @@ void xmrig::OclWorker::start() } while (!Nonce::isOutdated(Nonce::OPENCL, m_job.sequence())) { - if (m_interleave) { - m_interleave->adjustDelay(m_id); - } + m_sharedData.adjustDelay(m_id); const uint64_t t = Chrono::steadyMSecs(); @@ -233,9 +229,7 @@ void xmrig::OclWorker::storeStats(uint64_t t) m_count += m_intensity; - if (m_interleave) { - m_interleave->setRunTime(Chrono::steadyMSecs() - t); - } + m_sharedData.setRunTime(Chrono::steadyMSecs() - t); Worker::storeStats(); } diff --git a/src/backend/opencl/OclWorker.h b/src/backend/opencl/OclWorker.h index 93de8afd..76cb63db 100644 --- a/src/backend/opencl/OclWorker.h +++ b/src/backend/opencl/OclWorker.h @@ -67,7 +67,7 @@ private: const Miner *m_miner; const uint32_t m_intensity; IOclRunner *m_runner = nullptr; - OclInterleavePtr m_interleave; + OclSharedData &m_sharedData; WorkerJob<1> m_job; }; diff --git a/src/backend/opencl/opencl.cmake b/src/backend/opencl/opencl.cmake index c5a6335f..37675717 100644 --- a/src/backend/opencl/opencl.cmake +++ b/src/backend/opencl/opencl.cmake @@ -14,7 +14,6 @@ if (WITH_OPENCL) src/backend/opencl/OclCache.h src/backend/opencl/OclConfig.h src/backend/opencl/OclGenerator.h - src/backend/opencl/OclInterleave.h src/backend/opencl/OclLaunchData.h src/backend/opencl/OclThread.h src/backend/opencl/OclThreads.h @@ -22,6 +21,8 @@ if (WITH_OPENCL) src/backend/opencl/runners/OclBaseRunner.h src/backend/opencl/runners/OclCnRunner.h src/backend/opencl/runners/tools/OclCnR.h + src/backend/opencl/runners/tools/OclSharedData.h + src/backend/opencl/runners/tools/OclSharedState.h src/backend/opencl/wrappers/OclContext.h src/backend/opencl/wrappers/OclDevice.h src/backend/opencl/wrappers/OclError.h @@ -42,7 +43,6 @@ if (WITH_OPENCL) src/backend/opencl/OclBackend.cpp src/backend/opencl/OclCache.cpp src/backend/opencl/OclConfig.cpp - src/backend/opencl/OclInterleave.cpp src/backend/opencl/OclLaunchData.cpp src/backend/opencl/OclThread.cpp src/backend/opencl/OclThreads.cpp @@ -50,6 +50,8 @@ if (WITH_OPENCL) src/backend/opencl/runners/OclBaseRunner.cpp src/backend/opencl/runners/OclCnRunner.cpp src/backend/opencl/runners/tools/OclCnR.cpp + src/backend/opencl/runners/tools/OclSharedData.cpp + src/backend/opencl/runners/tools/OclSharedState.cpp src/backend/opencl/wrappers/OclContext.cpp src/backend/opencl/wrappers/OclDevice.cpp src/backend/opencl/wrappers/OclError.cpp @@ -78,7 +80,6 @@ if (WITH_OPENCL) src/backend/opencl/runners/OclRxBaseRunner.h src/backend/opencl/runners/OclRxJitRunner.h src/backend/opencl/runners/OclRxVmRunner.h - src/backend/opencl/runners/tools/OclRxDataset.h ) list(APPEND SOURCES_BACKEND_OPENCL @@ -95,7 +96,6 @@ if (WITH_OPENCL) src/backend/opencl/runners/OclRxBaseRunner.cpp src/backend/opencl/runners/OclRxJitRunner.cpp src/backend/opencl/runners/OclRxVmRunner.cpp - src/backend/opencl/runners/tools/OclRxDataset.cpp ) endif() diff --git a/src/backend/opencl/runners/OclBaseRunner.cpp b/src/backend/opencl/runners/OclBaseRunner.cpp index 71b35edc..d8497e94 100644 --- a/src/backend/opencl/runners/OclBaseRunner.cpp +++ b/src/backend/opencl/runners/OclBaseRunner.cpp @@ -23,10 +23,11 @@ */ +#include "backend/opencl/runners/OclBaseRunner.h" #include "backend/opencl/cl/OclSource.h" #include "backend/opencl/OclCache.h" #include "backend/opencl/OclLaunchData.h" -#include "backend/opencl/runners/OclBaseRunner.h" +#include "backend/opencl/runners/tools/OclSharedState.h" #include "backend/opencl/wrappers/OclError.h" #include "backend/opencl/wrappers/OclLib.h" #include "base/io/log/Log.h" @@ -34,6 +35,9 @@ #include "crypto/common/VirtualMemory.h" +constexpr size_t oneGiB = 1024 * 1024 * 1024; + + xmrig::OclBaseRunner::OclBaseRunner(size_t id, const OclLaunchData &data) : m_algorithm(data.algorithm), m_ctx(data.ctx), @@ -93,16 +97,17 @@ void xmrig::OclBaseRunner::build() void xmrig::OclBaseRunner::init() { - m_queue = OclLib::createCommandQueue(m_ctx, data().device.id()); + m_queue = OclLib::createCommandQueue(m_ctx, data().device.id()); - constexpr size_t oneGiB = 1024 * 1024 * 1024; - size_t size = bufferSize(); + size_t size = align(bufferSize()); if (size < oneGiB && data().device.vendorId() == OCL_VENDOR_AMD && data().device.freeMemSize() >= oneGiB) { - size = oneGiB; + m_buffer = OclSharedState::get(data().device.index()).createBuffer(m_ctx, size, m_offset); + } + else { + m_buffer = OclLib::createBuffer(m_ctx, CL_MEM_READ_WRITE, size); } - m_buffer = OclLib::createBuffer(m_ctx, CL_MEM_READ_WRITE, size); m_input = createSubBuffer(CL_MEM_READ_ONLY | CL_MEM_HOST_WRITE_ONLY, Job::kMaxBlobSize); m_output = createSubBuffer(CL_MEM_READ_WRITE, sizeof(cl_uint) * 0x100); } diff --git a/src/backend/opencl/runners/OclRxBaseRunner.cpp b/src/backend/opencl/runners/OclRxBaseRunner.cpp index 767b1083..fa0259b4 100644 --- a/src/backend/opencl/runners/OclRxBaseRunner.cpp +++ b/src/backend/opencl/runners/OclRxBaseRunner.cpp @@ -30,6 +30,7 @@ #include "backend/opencl/kernels/rx/FindSharesKernel.h" #include "backend/opencl/kernels/rx/HashAesKernel.h" #include "backend/opencl/OclLaunchData.h" +#include "backend/opencl/runners/tools/OclSharedState.h" #include "backend/opencl/wrappers/OclLib.h" #include "base/net/stratum/Job.h" #include "crypto/rx/Rx.h" @@ -75,6 +76,7 @@ xmrig::OclRxBaseRunner::~OclRxBaseRunner() OclLib::release(m_hashes); OclLib::release(m_rounding); OclLib::release(m_scratchpads); + OclLib::release(m_dataset); } @@ -120,7 +122,7 @@ void xmrig::OclRxBaseRunner::set(const Job &job, uint8_t *blob) m_seed = job.seed(); auto dataset = Rx::dataset(job, 0); - enqueueWriteBuffer(data().dataset->get(), CL_TRUE, 0, dataset->size(), dataset->raw()); + enqueueWriteBuffer(m_dataset, CL_TRUE, 0, dataset->size(), dataset->raw()); } if (job.size() < Job::kMaxBlobSize) { @@ -177,4 +179,5 @@ void xmrig::OclRxBaseRunner::init() m_hashes = createSubBuffer(CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, 64 * m_intensity); m_entropy = createSubBuffer(CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, (128 + 2560) * m_intensity); m_rounding = createSubBuffer(CL_MEM_READ_WRITE | CL_MEM_HOST_NO_ACCESS, sizeof(uint32_t) * m_intensity); + m_dataset = OclSharedState::get(data().device.index()).dataset(); } diff --git a/src/backend/opencl/runners/OclRxBaseRunner.h b/src/backend/opencl/runners/OclRxBaseRunner.h index 48b0ff8e..c7770e6c 100644 --- a/src/backend/opencl/runners/OclRxBaseRunner.h +++ b/src/backend/opencl/runners/OclRxBaseRunner.h @@ -62,6 +62,7 @@ protected: Blake2bHashRegistersKernel *m_blake2b_hash_registers_64 = nullptr; Blake2bInitialHashKernel *m_blake2b_initial_hash = nullptr; Buffer m_seed; + cl_mem m_dataset = nullptr; cl_mem m_entropy = nullptr; cl_mem m_hashes = nullptr; cl_mem m_rounding = nullptr; diff --git a/src/backend/opencl/runners/OclRxJitRunner.cpp b/src/backend/opencl/runners/OclRxJitRunner.cpp index 29020fe1..ca316333 100644 --- a/src/backend/opencl/runners/OclRxJitRunner.cpp +++ b/src/backend/opencl/runners/OclRxJitRunner.cpp @@ -74,7 +74,7 @@ void xmrig::OclRxJitRunner::build() } m_randomx_run = new RxRunKernel(m_asmProgram); - m_randomx_run->setArgs(data().dataset->get(), m_scratchpads, m_registers, m_rounding, m_programs, m_intensity, m_algorithm); + m_randomx_run->setArgs(m_dataset, m_scratchpads, m_registers, m_rounding, m_programs, m_intensity, m_algorithm); } diff --git a/src/backend/opencl/runners/OclRxVmRunner.cpp b/src/backend/opencl/runners/OclRxVmRunner.cpp index 193b68f0..3a30d561 100644 --- a/src/backend/opencl/runners/OclRxVmRunner.cpp +++ b/src/backend/opencl/runners/OclRxVmRunner.cpp @@ -70,7 +70,7 @@ void xmrig::OclRxVmRunner::build() m_init_vm->setArgs(m_entropy, m_vm_states, m_rounding); m_execute_vm = new ExecuteVmKernel(m_program); - m_execute_vm->setArgs(m_vm_states, m_rounding, m_scratchpads, data().dataset->get(), m_intensity); + m_execute_vm->setArgs(m_vm_states, m_rounding, m_scratchpads, m_dataset, m_intensity); } diff --git a/src/backend/opencl/OclInterleave.cpp b/src/backend/opencl/runners/tools/OclSharedData.cpp similarity index 65% rename from src/backend/opencl/OclInterleave.cpp rename to src/backend/opencl/runners/tools/OclSharedData.cpp index d7226f41..355ab775 100644 --- a/src/backend/opencl/OclInterleave.cpp +++ b/src/backend/opencl/runners/tools/OclSharedData.cpp @@ -23,17 +23,44 @@ */ -#include "backend/opencl/OclInterleave.h" +#include "backend/opencl/runners/tools/OclSharedData.h" +#include "backend/opencl/wrappers/OclLib.h" #include "base/io/log/Log.h" #include "base/tools/Chrono.h" +#include "crypto/rx/Rx.h" +#include "crypto/rx/RxDataset.h" +#include #include +#include #include -uint64_t xmrig::OclInterleave::adjustDelay(size_t id) +constexpr size_t oneGiB = 1024 * 1024 * 1024; + + +cl_mem xmrig::OclSharedData::createBuffer(cl_context context, size_t size, size_t &offset) { + std::lock_guard lock(m_mutex); + + offset += size * m_offset++; + size = std::max(size * m_threads, oneGiB); + + if (!m_buffer) { + m_buffer = OclLib::createBuffer(context, CL_MEM_READ_WRITE, size); + } + + return OclLib::retain(m_buffer); +} + + +uint64_t xmrig::OclSharedData::adjustDelay(size_t id) +{ + if (m_threads < 2) { + return 0; + } + const uint64_t t0 = Chrono::steadyMSecs(); uint64_t delay = 0; @@ -69,8 +96,12 @@ uint64_t xmrig::OclInterleave::adjustDelay(size_t id) } -uint64_t xmrig::OclInterleave::resumeDelay(size_t id) +uint64_t xmrig::OclSharedData::resumeDelay(size_t id) { + if (m_threads < 2) { + return 0; + } + uint64_t delay = 0; { @@ -99,14 +130,28 @@ uint64_t xmrig::OclInterleave::resumeDelay(size_t id) } -void xmrig::OclInterleave::setResumeCounter(uint32_t value) +void xmrig::OclSharedData::release() { + OclLib::release(m_buffer); + +# ifdef XMRIG_ALGO_RANDOMX + OclLib::release(m_dataset); +# endif +} + + +void xmrig::OclSharedData::setResumeCounter(uint32_t value) +{ + if (m_threads < 2) { + return; + } + std::lock_guard lock(m_mutex); m_resumeCounter = value; } -void xmrig::OclInterleave::setRunTime(uint64_t time) +void xmrig::OclSharedData::setRunTime(uint64_t time) { // averagingBias = 1.0 - only the last delta time is taken into account // averagingBias = 0.5 - the last delta time has the same weight as all the previous ones combined @@ -116,3 +161,34 @@ void xmrig::OclInterleave::setRunTime(uint64_t time) std::lock_guard lock(m_mutex); m_averageRunTime = m_averageRunTime * (1.0 - averagingBias) + time * averagingBias; } + + +#ifdef XMRIG_ALGO_RANDOMX +cl_mem xmrig::OclSharedData::dataset() const +{ + if (!m_dataset) { + throw std::runtime_error("RandomX dataset is not available"); + } + + return OclLib::retain(m_dataset); +} + + +void xmrig::OclSharedData::createDataset(cl_context ctx, const Job &job, bool host) +{ + if (m_dataset) { + return; + } + + cl_int ret; + + if (host) { + auto dataset = Rx::dataset(job, 0); + + m_dataset = OclLib::createBuffer(ctx, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, RxDataset::maxSize(), dataset->raw(), &ret); + } + else { + m_dataset = OclLib::createBuffer(ctx, CL_MEM_READ_ONLY, RxDataset::maxSize(), nullptr, &ret); + } +} +#endif diff --git a/src/backend/opencl/OclInterleave.h b/src/backend/opencl/runners/tools/OclSharedData.h similarity index 67% rename from src/backend/opencl/OclInterleave.h rename to src/backend/opencl/runners/tools/OclSharedData.h index 66327295..caf7b4d6 100644 --- a/src/backend/opencl/OclInterleave.h +++ b/src/backend/opencl/runners/tools/OclSharedData.h @@ -22,42 +22,62 @@ * along with this program. If not, see . */ -#ifndef XMRIG_OCLINTERLEAVE_H -#define XMRIG_OCLINTERLEAVE_H +#ifndef XMRIG_OCLSHAREDDATA_H +#define XMRIG_OCLSHAREDDATA_H #include #include +using cl_context = struct _cl_context *; +using cl_mem = struct _cl_mem *; + + namespace xmrig { -class OclInterleave +class Job; + + +class OclSharedData { public: - OclInterleave() = delete; - inline OclInterleave(size_t threads) : m_threads(threads) {} + OclSharedData() = default; + cl_mem createBuffer(cl_context context, size_t size, size_t &offset); uint64_t adjustDelay(size_t id); uint64_t resumeDelay(size_t id); + void release(); void setResumeCounter(uint32_t value); void setRunTime(uint64_t time); + inline size_t threads() const { return m_threads; } + + inline OclSharedData &operator++() { ++m_threads; return *this; } + +# ifdef XMRIG_ALGO_RANDOMX + cl_mem dataset() const; + void createDataset(cl_context ctx, const Job &job, bool host); +# endif + private: - const size_t m_threads; + cl_mem m_buffer = nullptr; double m_averageRunTime = 0.0; double m_threshold = 0.95; + size_t m_offset = 0; + size_t m_threads = 0; std::mutex m_mutex; uint32_t m_resumeCounter = 0; uint64_t m_timestamp = 0; + +# ifdef XMRIG_ALGO_RANDOMX + cl_mem m_dataset = nullptr; +# endif }; -using OclInterleavePtr = std::shared_ptr; - - } /* namespace xmrig */ -#endif /* XMRIG_OCLINTERLEAVE_H */ +#endif /* XMRIG_OCLSHAREDDATA_H */ diff --git a/src/backend/opencl/runners/tools/OclRxDataset.cpp b/src/backend/opencl/runners/tools/OclSharedState.cpp similarity index 59% rename from src/backend/opencl/runners/tools/OclRxDataset.cpp rename to src/backend/opencl/runners/tools/OclSharedState.cpp index b1d83bd0..0b16a301 100644 --- a/src/backend/opencl/runners/tools/OclRxDataset.cpp +++ b/src/backend/opencl/runners/tools/OclSharedState.cpp @@ -23,32 +23,52 @@ */ -#include "backend/opencl/runners/tools/OclRxDataset.h" -#include "backend/opencl/wrappers/OclLib.h" -#include "crypto/rx/Rx.h" -#include "crypto/rx/RxDataset.h" +#include "backend/opencl/runners/tools/OclSharedState.h" +#include "backend/opencl/runners/tools/OclSharedData.h" -void xmrig::OclRxDataset::createBuffer(cl_context ctx, const Job &job, bool host) +#include +#include + + +namespace xmrig { + + +static std::map map; + + +} // namespace xmrig + + +xmrig::OclSharedData &xmrig::OclSharedState::get(uint32_t index) { - if (m_dataset) { - return; - } - - cl_int ret; - - if (host) { - auto dataset = Rx::dataset(job, 0); - - m_dataset = OclLib::createBuffer(ctx, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, RxDataset::maxSize(), dataset->raw(), &ret); - } - else { - m_dataset = OclLib::createBuffer(ctx, CL_MEM_READ_ONLY, RxDataset::maxSize(), nullptr, &ret); - } + return map[index]; } -xmrig::OclRxDataset::~OclRxDataset() +void xmrig::OclSharedState::release() { - OclLib::release(m_dataset); + for (auto &kv : map) { + kv.second.release(); + } + + map.clear(); +} + + +void xmrig::OclSharedState::start(const std::vector &threads, const Job &job) +{ + assert(map.empty()); + + for (const auto &data : threads) { + auto &sharedData = map[data.device.index()]; + + ++sharedData; + +# ifdef XMRIG_ALGO_RANDOMX + if (data.algorithm.family() == Algorithm::RANDOM_X) { + sharedData.createDataset(data.ctx, job, data.thread.isDatasetHost()); + } +# endif + } } diff --git a/src/backend/opencl/runners/tools/OclRxDataset.h b/src/backend/opencl/runners/tools/OclSharedState.h similarity index 69% rename from src/backend/opencl/runners/tools/OclRxDataset.h rename to src/backend/opencl/runners/tools/OclSharedState.h index 314a2f5d..610056cd 100644 --- a/src/backend/opencl/runners/tools/OclRxDataset.h +++ b/src/backend/opencl/runners/tools/OclSharedState.h @@ -22,47 +22,26 @@ * along with this program. If not, see . */ -#ifndef XMRIG_OCLRXDATASET_H -#define XMRIG_OCLRXDATASET_H +#ifndef XMRIG_OCLSHAREDSTATE_H +#define XMRIG_OCLSHAREDSTATE_H -#include "base/tools/Object.h" - - -#include - - -using cl_context = struct _cl_context *; -using cl_mem = struct _cl_mem *; +#include "backend/opencl/OclLaunchData.h" namespace xmrig { -class Job; - - -class OclRxDataset +class OclSharedState { public: - XMRIG_DISABLE_COPY_MOVE(OclRxDataset) - - OclRxDataset() = default; - ~OclRxDataset(); - - inline cl_mem get() const { return m_dataset; } - - void createBuffer(cl_context ctx,const Job &job, bool host); - -private: - cl_mem m_dataset = nullptr; + static OclSharedData &get(uint32_t index); + static void release(); + static void start(const std::vector &threads, const Job &job); }; -using OclRxDatasetPtr = std::shared_ptr; - - } /* namespace xmrig */ -#endif /* XMRIG_OCLINTERLEAVE_H */ +#endif /* XMRIG_OCLSHAREDSTATE_H */ diff --git a/src/backend/opencl/wrappers/OclContext.cpp b/src/backend/opencl/wrappers/OclContext.cpp index a2559335..eed4272c 100644 --- a/src/backend/opencl/wrappers/OclContext.cpp +++ b/src/backend/opencl/wrappers/OclContext.cpp @@ -24,6 +24,7 @@ #include "backend/opencl/wrappers/OclContext.h" +#include "backend/opencl/runners/tools/OclSharedState.h" #include "backend/opencl/wrappers/OclLib.h" @@ -42,7 +43,7 @@ xmrig::OclContext::~OclContext() } -bool xmrig::OclContext::init(const std::vector &devices, std::vector &threads, const Job &job) +bool xmrig::OclContext::init(const std::vector &devices, std::vector &threads) { if (!m_ctx) { std::vector ids(devices.size()); @@ -59,12 +60,6 @@ bool xmrig::OclContext::init(const std::vector &devices, std::vector< for (OclLaunchData &data : threads) { data.ctx = m_ctx; - -# ifdef XMRIG_ALGO_RANDOMX - if (data.algorithm.family() == Algorithm::RANDOM_X) { - data.dataset->createBuffer(m_ctx, job, data.thread.isDatasetHost()); - } -# endif } return true; diff --git a/src/backend/opencl/wrappers/OclContext.h b/src/backend/opencl/wrappers/OclContext.h index 8f2cc432..fb45358e 100644 --- a/src/backend/opencl/wrappers/OclContext.h +++ b/src/backend/opencl/wrappers/OclContext.h @@ -49,7 +49,7 @@ public: OclContext(const OclDevice &device); ~OclContext(); - bool init(const std::vector &devices, std::vector &threads, const Job &job); + bool init(const std::vector &devices, std::vector &threads); inline bool isValid() const { return m_ctx != nullptr; } inline cl_context ctx() const { return m_ctx; } diff --git a/src/backend/opencl/wrappers/OclLib.cpp b/src/backend/opencl/wrappers/OclLib.cpp index 826b88c5..1b530bae 100644 --- a/src/backend/opencl/wrappers/OclLib.cpp +++ b/src/backend/opencl/wrappers/OclLib.cpp @@ -73,6 +73,7 @@ static const char *kReleaseDevice = "clReleaseDevice"; static const char *kReleaseKernel = "clReleaseKernel"; static const char *kReleaseMemObject = "clReleaseMemObject"; static const char *kReleaseProgram = "clReleaseProgram"; +static const char *kRetainMemObject = "clRetainMemObject"; static const char *kRetainProgram = "clRetainProgram"; static const char *kSetKernelArg = "clSetKernelArg"; static const char *kSetMemObjectDestructorCallback = "clSetMemObjectDestructorCallback"; @@ -106,6 +107,7 @@ typedef cl_int (CL_API_CALL *releaseDevice_t)(cl_device_id device); typedef cl_int (CL_API_CALL *releaseKernel_t)(cl_kernel); typedef cl_int (CL_API_CALL *releaseMemObject_t)(cl_mem); typedef cl_int (CL_API_CALL *releaseProgram_t)(cl_program); +typedef cl_int (CL_API_CALL *retainMemObject_t)(cl_mem); typedef cl_int (CL_API_CALL *retainProgram_t)(cl_program); typedef cl_int (CL_API_CALL *setKernelArg_t)(cl_kernel, cl_uint, size_t, const void *); typedef cl_int (CL_API_CALL *setMemObjectDestructorCallback_t)(cl_mem, void (CL_CALLBACK *)(cl_mem, void *), void *); @@ -148,6 +150,7 @@ static releaseDevice_t pReleaseDevice = nu static releaseKernel_t pReleaseKernel = nullptr; static releaseMemObject_t pReleaseMemObject = nullptr; static releaseProgram_t pReleaseProgram = nullptr; +static retainMemObject_t pRetainMemObject = nullptr; static retainProgram_t pRetainProgram = nullptr; static setKernelArg_t pSetKernelArg = nullptr; static setMemObjectDestructorCallback_t pSetMemObjectDestructorCallback = nullptr; @@ -239,6 +242,7 @@ bool xmrig::OclLib::load() DLSYM(SetMemObjectDestructorCallback); DLSYM(CreateSubBuffer); DLSYM(RetainProgram); + DLSYM(RetainMemObject); # if defined(CL_VERSION_2_0) uv_dlsym(&oclLib, kCreateCommandQueueWithProperties, reinterpret_cast(&pCreateCommandQueueWithProperties)); @@ -670,6 +674,18 @@ cl_mem xmrig::OclLib::createSubBuffer(cl_mem buffer, cl_mem_flags flags, size_t } +cl_mem xmrig::OclLib::retain(cl_mem memobj) noexcept +{ + assert(pRetainMemObject != nullptr); + + if (memobj != nullptr) { + pRetainMemObject(memobj); + } + + return memobj; +} + + cl_program xmrig::OclLib::createProgramWithBinary(cl_context context, cl_uint num_devices, const cl_device_id *device_list, const size_t *lengths, const unsigned char **binaries, cl_int *binary_status, cl_int *errcode_ret) noexcept { assert(pCreateProgramWithBinary != nullptr); diff --git a/src/backend/opencl/wrappers/OclLib.h b/src/backend/opencl/wrappers/OclLib.h index e9e4b8f3..0c0eb0d4 100644 --- a/src/backend/opencl/wrappers/OclLib.h +++ b/src/backend/opencl/wrappers/OclLib.h @@ -79,6 +79,7 @@ public: static cl_mem createBuffer(cl_context context, cl_mem_flags flags, size_t size, void *host_ptr, cl_int *errcode_ret) noexcept; static cl_mem createSubBuffer(cl_mem buffer, cl_mem_flags flags, size_t offset, size_t size, cl_int *errcode_ret) noexcept; static cl_mem createSubBuffer(cl_mem buffer, cl_mem_flags flags, size_t offset, size_t size); + static cl_mem retain(cl_mem memobj) noexcept; static cl_program createProgramWithBinary(cl_context context, cl_uint num_devices, const cl_device_id *device_list, const size_t *lengths, const unsigned char **binaries, cl_int *binary_status, cl_int *errcode_ret) noexcept; static cl_program createProgramWithSource(cl_context context, cl_uint count, const char **strings, const size_t *lengths, cl_int *errcode_ret) noexcept; static cl_program retain(cl_program program) noexcept; diff --git a/src/crypto/rx/Rx.cpp b/src/crypto/rx/Rx.cpp index 76ab07c4..d0674b29 100644 --- a/src/crypto/rx/Rx.cpp +++ b/src/crypto/rx/Rx.cpp @@ -47,6 +47,7 @@ #endif +#include #include #include #include @@ -96,12 +97,14 @@ class RxPrivate public: XMRIG_DISABLE_COPY_MOVE(RxPrivate) - inline RxPrivate() + inline RxPrivate() : + m_counter(0), + m_last(0) { m_async = new uv_async_t; m_async->data = this; - uv_async_init(uv_default_loop(), m_async, RxPrivate::onReady); + uv_async_init(uv_default_loop(), m_async, [](uv_async_t *) { d_ptr->onReady(); }); # ifdef XMRIG_FEATURE_HWLOC if (Cpu::info()->nodes() > 1) { @@ -130,11 +133,12 @@ public: inline bool isNUMA() const { return m_numa; } + inline bool isReady(const Job &job) const { return m_ready == count() && m_algorithm == job.algorithm() && m_seed == job.seed(); } inline const Algorithm &algorithm() const { return m_algorithm; } inline const Buffer &seed() const { return m_seed; } inline size_t count() const { return isNUMA() ? datasets.size() : 1; } - inline void asyncSend() { m_ready++; if (m_ready == count()) { uv_async_send(m_async); } } - + inline uint64_t counter() { return m_counter.load(std::memory_order_relaxed); } + inline void asyncSend(uint64_t counter) { m_ready++; if (m_ready == count()) { m_last = counter; uv_async_send(m_async); } } static void allocate(uint32_t nodeId) { @@ -176,14 +180,14 @@ public: } - static void initDataset(uint32_t nodeId, uint32_t threads) + static void initDataset(uint32_t nodeId, uint32_t threads, uint64_t counter) { std::lock_guard lock(mutex); const uint64_t ts = Chrono::steadyMSecs(); d_ptr->getOrAllocate(nodeId)->init(d_ptr->seed(), threads); - d_ptr->asyncSend(); + d_ptr->asyncSend(counter); LOG_INFO("%s" CYAN_BOLD("#%u") GREEN(" init done ") CYAN_BOLD("%zu/%zu") BLACK_BOLD(" (%" PRIu64 " ms)"), tag, nodeId, d_ptr->m_ready, d_ptr->count(), Chrono::steadyMSecs() - ts); } @@ -222,32 +226,31 @@ public: m_hugePages = hugePages; m_listener = listener; m_seed = job.seed(); - } - - inline bool isReady(const Job &job) - { - return m_ready == count() && m_algorithm == job.algorithm() && m_seed == job.seed(); + ++m_counter; } std::map datasets; private: - static void onReady(uv_async_t *) + inline void onReady() { - if (d_ptr->m_listener) { - d_ptr->m_listener->onDatasetReady(); + if (m_listener && counter() == m_last.load(std::memory_order_relaxed)) { + m_listener->onDatasetReady(); } } + Algorithm m_algorithm; bool m_hugePages = true; bool m_numa = true; Buffer m_seed; IRxListener *m_listener = nullptr; size_t m_ready = 0; - uv_async_t *m_async; + std::atomic m_counter; + std::atomic m_last; + uv_async_t *m_async = nullptr; }; @@ -269,6 +272,7 @@ bool xmrig::Rx::init(const Job &job, int initThreads, bool hugePages, bool numa, d_ptr->setState(job, hugePages, numa, listener); const uint32_t threads = initThreads < 1 ? static_cast(Cpu::info()->threads()) : static_cast(initThreads); const String buf = Buffer::toHex(job.seed().data(), 8); + const uint64_t counter = d_ptr->counter(); LOG_INFO("%s" MAGENTA_BOLD("init dataset%s") " algo " WHITE_BOLD("%s (") CYAN_BOLD("%u") WHITE_BOLD(" threads)") BLACK_BOLD(" seed %s..."), tag, @@ -281,14 +285,14 @@ bool xmrig::Rx::init(const Job &job, int initThreads, bool hugePages, bool numa, # ifdef XMRIG_FEATURE_HWLOC if (d_ptr->isNUMA()) { for (auto const &item : d_ptr->datasets) { - std::thread thread(RxPrivate::initDataset, item.first, threads); + std::thread thread(RxPrivate::initDataset, item.first, threads, counter); thread.detach(); } } else # endif { - std::thread thread(RxPrivate::initDataset, 0, threads); + std::thread thread(RxPrivate::initDataset, 0, threads, counter); thread.detach(); } @@ -311,7 +315,7 @@ xmrig::RxDataset *xmrig::Rx::dataset(const Job &job, uint32_t nodeId) return nullptr; } - return d_ptr->datasets.at(d_ptr->isNUMA() ? nodeId : 0); + return d_ptr->datasets.at(d_ptr->isNUMA() ? (d_ptr->datasets.count(nodeId) ? nodeId : HwlocCpuInfo::nodeIndexes().front()) : 0); } diff --git a/src/crypto/rx/RxVm.h b/src/crypto/rx/RxVm.h index 5154b66d..30a31c2e 100644 --- a/src/crypto/rx/RxVm.h +++ b/src/crypto/rx/RxVm.h @@ -63,4 +63,4 @@ private: } /* namespace xmrig */ -#endif /* XMRIG_RX_CACHE_H */ +#endif /* XMRIG_RX_VM_H */ diff --git a/src/version.h b/src/version.h index f803340d..7d7c996d 100644 --- a/src/version.h +++ b/src/version.h @@ -28,14 +28,14 @@ #define APP_ID "xmrig" #define APP_NAME "XMRig" #define APP_DESC "XMRig miner" -#define APP_VERSION "4.2.0-beta" +#define APP_VERSION "4.3.0-evo" #define APP_DOMAIN "xmrig.com" #define APP_SITE "www.xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2019 xmrig.com" #define APP_KIND "miner" #define APP_VER_MAJOR 4 -#define APP_VER_MINOR 2 +#define APP_VER_MINOR 3 #define APP_VER_PATCH 0 #ifdef _MSC_VER