mirror of
https://github.com/xmrig/xmrig.git
synced 2024-11-18 10:01:06 +00:00
Merge branch 'evo' into beta
This commit is contained in:
commit
14441ab5f9
24 changed files with 322 additions and 292 deletions
|
@ -1,3 +1,10 @@
|
|||
# v2.99.4-beta
|
||||
- [#1062](https://github.com/xmrig/xmrig/issues/1062) Fixed 32 bit support. **32 bit is slow and deprecated**.
|
||||
- [#1088](https://github.com/xmrig/xmrig/pull/1088) Fixed macOS compilation.
|
||||
- [#1095](https://github.com/xmrig/xmrig/pull/1095) Fixed compatibility with hwloc 1.10.x.
|
||||
- Optimized RandomX initialization and switching, fixed rare crash when re-initialize dataset.
|
||||
- Fixed ARM build with hwloc.
|
||||
|
||||
# v2.99.3-beta
|
||||
- [#1082](https://github.com/xmrig/xmrig/issues/1082) Fixed hwloc auto configuration on AMD FX CPUs.
|
||||
- Added command line option `--export-topology` for export hwloc topology to a XML file.
|
||||
|
|
|
@ -34,7 +34,11 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
|
|||
endif()
|
||||
|
||||
if (WIN32)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
|
||||
else()
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static -Wl,--large-address-aware")
|
||||
endif()
|
||||
else()
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
|
||||
endif()
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#define XMRIG_THREAD_H
|
||||
|
||||
|
||||
#include <uv.h>
|
||||
#include <thread>
|
||||
|
||||
|
||||
#include "backend/common/interfaces/IWorker.h"
|
||||
|
@ -43,21 +43,21 @@ class Thread
|
|||
{
|
||||
public:
|
||||
inline Thread(IBackend *backend, size_t index, const T &config) : m_index(index), m_config(config), m_backend(backend) {}
|
||||
inline ~Thread() { uv_thread_join(&m_thread); delete m_worker; }
|
||||
inline ~Thread() { m_thread.join(); delete m_worker; }
|
||||
|
||||
inline const T &config() const { return m_config; }
|
||||
inline IBackend *backend() const { return m_backend; }
|
||||
inline IWorker *worker() const { return m_worker; }
|
||||
inline size_t index() const { return m_index; }
|
||||
inline void setWorker(IWorker *worker) { m_worker = worker; }
|
||||
inline void start(void (*callback) (void *)) { uv_thread_create(&m_thread, callback, this); }
|
||||
inline void start(void (*callback) (void *)) { m_thread = std::thread(callback, this); }
|
||||
|
||||
private:
|
||||
const size_t m_index = 0;
|
||||
const T m_config;
|
||||
IBackend *m_backend;
|
||||
IWorker *m_worker = nullptr;
|
||||
uv_thread_t m_thread;
|
||||
std::thread m_thread;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -49,7 +49,8 @@ namespace xmrig {
|
|||
extern template class Threads<CpuThread>;
|
||||
|
||||
|
||||
static const String kType = "cpu";
|
||||
static const char *tag = CYAN_BG_BOLD(" cpu ");
|
||||
static const String kType = "cpu";
|
||||
|
||||
|
||||
struct LaunchStatus
|
||||
|
@ -94,7 +95,8 @@ public:
|
|||
|
||||
inline void start()
|
||||
{
|
||||
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"),
|
||||
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,
|
||||
profileName.data(),
|
||||
threads.size(),
|
||||
algo.memory() / 1024
|
||||
|
@ -170,12 +172,8 @@ const xmrig::String &xmrig::CpuBackend::type() const
|
|||
}
|
||||
|
||||
|
||||
void xmrig::CpuBackend::prepare(const Job &nextJob)
|
||||
void xmrig::CpuBackend::prepare(const Job &)
|
||||
{
|
||||
if (nextJob.algorithm().family() == Algorithm::RANDOM_X && nextJob.algorithm() != d_ptr->algo) {
|
||||
d_ptr->workers.stop();
|
||||
d_ptr->threads.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -207,9 +205,7 @@ void xmrig::CpuBackend::printHashrate(bool details)
|
|||
void xmrig::CpuBackend::setJob(const Job &job)
|
||||
{
|
||||
if (!isEnabled()) {
|
||||
d_ptr->workers.stop();
|
||||
d_ptr->threads.clear();
|
||||
return;
|
||||
return stop();
|
||||
}
|
||||
|
||||
const CpuConfig &cpu = d_ptr->controller->config()->cpu();
|
||||
|
@ -249,7 +245,8 @@ void xmrig::CpuBackend::start(IWorker *worker)
|
|||
const double percent = d_ptr->status.hugePages == 0 ? 0.0 : static_cast<double>(d_ptr->status.hugePages) / d_ptr->status.pages * 100.0;
|
||||
const size_t memory = d_ptr->status.ways * d_ptr->status.memory / 1024;
|
||||
|
||||
LOG_INFO(GREEN_BOLD("CPU READY") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\x1B[0m memory " CYAN_BOLD("%zu KB") BLACK_BOLD(" (%" PRIu64 " ms)"),
|
||||
LOG_INFO("%s" GREEN_BOLD(" READY") " threads " CYAN_BOLD("%zu(%zu)") " huge pages %s%zu/%zu %1.0f%%\x1B[0m memory " CYAN_BOLD("%zu KB") BLACK_BOLD(" (%" PRIu64 " ms)"),
|
||||
tag,
|
||||
d_ptr->status.threads, d_ptr->status.ways,
|
||||
(d_ptr->status.hugePages == d_ptr->status.pages ? GREEN_BOLD_S : (d_ptr->status.hugePages == 0 ? RED_BOLD_S : YELLOW_BOLD_S)),
|
||||
d_ptr->status.hugePages, d_ptr->status.pages, percent, memory,
|
||||
|
@ -265,7 +262,12 @@ void xmrig::CpuBackend::start(IWorker *worker)
|
|||
|
||||
void xmrig::CpuBackend::stop()
|
||||
{
|
||||
const uint64_t ts = Chrono::steadyMSecs();
|
||||
|
||||
d_ptr->workers.stop();
|
||||
d_ptr->threads.clear();
|
||||
|
||||
LOG_INFO("%s" YELLOW(" stopped") BLACK_BOLD(" (%" PRIu64 " ms)"), tag, Chrono::steadyMSecs() - ts);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -82,7 +82,9 @@ xmrig::CpuWorker<N>::~CpuWorker()
|
|||
template<size_t N>
|
||||
void xmrig::CpuWorker<N>::allocateRandomX_VM()
|
||||
{
|
||||
while (!Rx::isReady(m_job.currentJob(), m_node)) {
|
||||
RxDataset *dataset = Rx::dataset(m_job.currentJob(), m_node);
|
||||
|
||||
while (dataset == nullptr) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
|
||||
if (Nonce::sequence(Nonce::CPU) == 0) {
|
||||
|
@ -90,13 +92,6 @@ void xmrig::CpuWorker<N>::allocateRandomX_VM()
|
|||
}
|
||||
}
|
||||
|
||||
RxDataset *dataset = Rx::dataset(m_node);
|
||||
assert(dataset != nullptr);
|
||||
|
||||
if (!dataset) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_vm) {
|
||||
m_vm = new RxVm(dataset, m_memory->scratchpad(), !m_hwAES);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ if (WITH_HWLOC)
|
|||
endif()
|
||||
|
||||
set(SOURCES_CPUID
|
||||
src/backend/cpu/platform/BasicCpuInfo.cpp
|
||||
src/backend/cpu/platform/BasicCpuInfo.h
|
||||
src/backend/cpu/platform/HwlocCpuInfo.cpp
|
||||
src/backend/cpu/platform/HwlocCpuInfo.h
|
||||
|
@ -66,7 +65,10 @@ else()
|
|||
set(SOURCES_CPUID
|
||||
src/backend/cpu/platform/BasicCpuInfo.h
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
if (NOT WITH_LIBCPUID)
|
||||
if (XMRIG_ARM)
|
||||
set(SOURCES_CPUID ${SOURCES_CPUID} src/backend/cpu/platform/BasicCpuInfo_arm.cpp)
|
||||
else()
|
||||
|
|
|
@ -36,10 +36,10 @@
|
|||
|
||||
|
||||
xmrig::BasicCpuInfo::BasicCpuInfo() :
|
||||
m_aes(false),
|
||||
m_brand(),
|
||||
m_avx2(false),
|
||||
m_threads(std::thread::hardware_concurrency())
|
||||
m_threads(std::thread::hardware_concurrency()),
|
||||
m_aes(false),
|
||||
m_avx2(false)
|
||||
{
|
||||
# ifdef XMRIG_ARMv8
|
||||
memcpy(m_brand, "ARMv8", 5);
|
||||
|
|
|
@ -32,6 +32,12 @@
|
|||
#include <hwloc.h>
|
||||
|
||||
|
||||
#if HWLOC_API_VERSION < 0x00010b00
|
||||
# define HWLOC_OBJ_PACKAGE HWLOC_OBJ_SOCKET
|
||||
# define HWLOC_OBJ_NUMANODE HWLOC_OBJ_NODE
|
||||
#endif
|
||||
|
||||
|
||||
#include "backend/cpu/platform/HwlocCpuInfo.h"
|
||||
#include "base/io/log/Log.h"
|
||||
|
||||
|
@ -152,7 +158,21 @@ xmrig::HwlocCpuInfo::HwlocCpuInfo() : BasicCpuInfo(),
|
|||
# endif
|
||||
|
||||
hwloc_obj_t root = hwloc_get_root_obj(m_topology);
|
||||
snprintf(m_backend, sizeof m_backend, "hwloc/%s", hwloc_obj_get_info_by_name(root, "hwlocVersion"));
|
||||
|
||||
# if HWLOC_API_VERSION >= 0x00010b00
|
||||
const char *version = hwloc_obj_get_info_by_name(root, "hwlocVersion");
|
||||
if (version) {
|
||||
snprintf(m_backend, sizeof m_backend, "hwloc/%s", version);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
{
|
||||
snprintf(m_backend, sizeof m_backend, "hwloc/%d.%d.%d",
|
||||
(HWLOC_API_VERSION>>16)&0x000000ff,
|
||||
(HWLOC_API_VERSION>>8 )&0x000000ff,
|
||||
(HWLOC_API_VERSION )&0x000000ff
|
||||
);
|
||||
}
|
||||
|
||||
findCache(root, 2, 3, [this](hwloc_obj_t found) { this->m_cache[found->attr->cache.depth] += found->attr->cache.size; });
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
|
@ -69,14 +70,11 @@ public:
|
|||
inline LogPrivate() :
|
||||
m_buf()
|
||||
{
|
||||
uv_mutex_init(&m_mutex);
|
||||
}
|
||||
|
||||
|
||||
inline ~LogPrivate()
|
||||
{
|
||||
uv_mutex_destroy(&m_mutex);
|
||||
|
||||
for (ILogBackend *backend : m_backends) {
|
||||
delete backend;
|
||||
}
|
||||
|
@ -91,13 +89,14 @@ public:
|
|||
size_t size = 0;
|
||||
size_t offset = 0;
|
||||
|
||||
lock();
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
timestamp(level, size, offset);
|
||||
color(level, size);
|
||||
|
||||
const int rc = vsnprintf(m_buf + size, sizeof (m_buf) - offset - 32, fmt, args);
|
||||
if (rc < 0) {
|
||||
return unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
size += std::min(static_cast<size_t>(rc), sizeof (m_buf) - offset - 32);
|
||||
|
@ -119,16 +118,10 @@ public:
|
|||
fputs(txt.c_str(), stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
unlock();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
inline void lock() { uv_mutex_lock(&m_mutex); }
|
||||
inline void unlock() { uv_mutex_unlock(&m_mutex); }
|
||||
|
||||
|
||||
inline void timestamp(Log::Level level, size_t &size, size_t &offset)
|
||||
{
|
||||
if (level == Log::NONE) {
|
||||
|
@ -192,8 +185,8 @@ private:
|
|||
|
||||
|
||||
char m_buf[4096];
|
||||
std::mutex m_mutex;
|
||||
std::vector<ILogBackend*> m_backends;
|
||||
uv_mutex_t m_mutex;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -85,6 +85,8 @@ private:
|
|||
#define BLUE_BG_BOLD_S CSI "44;1m"
|
||||
#define MAGENTA_BG_S CSI "45m"
|
||||
#define MAGENTA_BG_BOLD_S CSI "45;1m"
|
||||
#define CYAN_BG_S CSI "46m"
|
||||
#define CYAN_BG_BOLD_S CSI "46;1m"
|
||||
|
||||
//color wrappings
|
||||
#define BLACK(x) BLACK_S x CLEAR
|
||||
|
@ -108,6 +110,8 @@ private:
|
|||
#define BLUE_BG_BOLD(x) BLUE_BG_BOLD_S x CLEAR
|
||||
#define MAGENTA_BG(x) MAGENTA_BG_S x CLEAR
|
||||
#define MAGENTA_BG_BOLD(x) MAGENTA_BG_BOLD_S x CLEAR
|
||||
#define CYAN_BG(x) CYAN_BG_S x CLEAR
|
||||
#define CYAN_BG_BOLD(x) CYAN_BG_BOLD_S x CLEAR
|
||||
|
||||
|
||||
#define LOG_EMERG(x, ...) xmrig::Log::print(xmrig::Log::EMERG, x, ##__VA_ARGS__)
|
||||
|
|
|
@ -160,3 +160,20 @@ void xmrig::Job::setDiff(uint64_t diff)
|
|||
m_rawTarget[16] = '\0';
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Job::copy(const Job &other)
|
||||
{
|
||||
m_algorithm = other.m_algorithm;
|
||||
m_nicehash = other.m_nicehash;
|
||||
m_size = other.m_size;
|
||||
m_clientId = other.m_clientId;
|
||||
m_id = other.m_id;
|
||||
m_diff = other.m_diff;
|
||||
m_height = other.m_height;
|
||||
m_target = other.m_target;
|
||||
m_index = other.m_index;
|
||||
|
||||
memcpy(m_blob, other.m_blob, sizeof (m_blob));
|
||||
memcpy(m_seedHash, other.m_seedHash, sizeof(m_seedHash));
|
||||
}
|
||||
|
|
|
@ -90,10 +90,13 @@ public:
|
|||
|
||||
inline bool operator==(const Job &other) const { return isEqual(other); }
|
||||
inline bool operator!=(const Job &other) const { return !isEqual(other); }
|
||||
inline Job &operator=(const Job &other) { copy(other); return *this; }
|
||||
|
||||
private:
|
||||
void copy(const Job &other);
|
||||
|
||||
Algorithm m_algorithm;
|
||||
bool m_nicehash = false;
|
||||
bool m_nicehash = false;
|
||||
size_t m_size = 0;
|
||||
String m_clientId;
|
||||
String m_id;
|
||||
|
|
|
@ -43,17 +43,20 @@ public:
|
|||
~Buffer();
|
||||
|
||||
|
||||
inline char *data() { return m_data; }
|
||||
inline const char *data() const { return m_data; }
|
||||
inline size_t size() const { return m_size; }
|
||||
inline void from(const Buffer &other) { from(other.data(), other.size()); }
|
||||
inline bool isEqual(const Buffer &other) const { return m_size == other.m_size && (m_size == 0 || memcmp(m_data, other.m_data, m_size) == 0); }
|
||||
inline char *data() { return m_data; }
|
||||
inline const char *data() const { return m_data; }
|
||||
inline size_t size() const { return m_size; }
|
||||
inline void from(const Buffer &other) { from(other.data(), other.size()); }
|
||||
|
||||
|
||||
void from(const char *data, size_t size);
|
||||
|
||||
|
||||
inline Buffer &operator=(const Buffer &other) { from(other); return *this; }
|
||||
inline Buffer &operator=(Buffer &&other) { move(std::move(other)); return *this; }
|
||||
inline bool operator!=(const Buffer &other) const { return !isEqual(other); }
|
||||
inline bool operator==(const Buffer &other) const { return isEqual(other); }
|
||||
inline Buffer &operator=(Buffer &&other) { move(std::move(other)); return *this; }
|
||||
inline Buffer &operator=(const Buffer &other) { from(other); return *this; }
|
||||
|
||||
|
||||
static Buffer allocUnsafe(size_t size);
|
||||
|
|
|
@ -59,6 +59,10 @@ public:
|
|||
inline MinerPrivate(Controller *controller) : controller(controller)
|
||||
{
|
||||
uv_rwlock_init(&rwlock);
|
||||
|
||||
# ifdef XMRIG_ALGO_RANDOMX
|
||||
Rx::init();
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -71,6 +75,10 @@ public:
|
|||
for (IBackend *backend : backends) {
|
||||
delete backend;
|
||||
}
|
||||
|
||||
# ifdef XMRIG_ALGO_RANDOMX
|
||||
Rx::destroy();
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -353,12 +361,18 @@ void xmrig::Miner::setEnabled(bool enabled)
|
|||
|
||||
void xmrig::Miner::setJob(const Job &job, bool donate)
|
||||
{
|
||||
d_ptr->algorithm = job.algorithm();
|
||||
|
||||
for (IBackend *backend : d_ptr->backends) {
|
||||
backend->prepare(job);
|
||||
}
|
||||
|
||||
# ifdef XMRIG_ALGO_RANDOMX
|
||||
if (d_ptr->algorithm.family() == Algorithm::RANDOM_X && job.algorithm().family() == Algorithm::RANDOM_X && !Rx::isReady(job)) {
|
||||
stop();
|
||||
}
|
||||
# endif
|
||||
|
||||
d_ptr->algorithm = job.algorithm();
|
||||
|
||||
uv_rwlock_wrlock(&d_ptr->rwlock);
|
||||
|
||||
const uint8_t index = donate ? 1 : 0;
|
||||
|
@ -372,7 +386,7 @@ void xmrig::Miner::setJob(const Job &job, bool donate)
|
|||
}
|
||||
|
||||
# ifdef XMRIG_ALGO_RANDOMX
|
||||
Rx::init(job,
|
||||
Rx::init(d_ptr->job,
|
||||
d_ptr->controller->config()->rx().threads(),
|
||||
d_ptr->controller->config()->cpu().isHugePages(),
|
||||
d_ptr->controller->config()->rx().isNUMA()
|
||||
|
|
|
@ -36,7 +36,10 @@ static const char *kAffinity = "affinity";
|
|||
static const char *kAsterisk = "*";
|
||||
static const char *kCpu = "cpu";
|
||||
static const char *kIntensity = "intensity";
|
||||
static const char *kRandomX = "randomx";
|
||||
|
||||
#ifdef XMRIG_ALGO_RANDOMX
|
||||
static const char *kRandomX = "randomx";
|
||||
#endif
|
||||
|
||||
|
||||
static inline uint64_t intensity(uint64_t av)
|
||||
|
|
|
@ -28,6 +28,10 @@
|
|||
#ifdef XMRIG_FEATURE_HWLOC
|
||||
# include <hwloc.h>
|
||||
# include "backend/cpu/platform/HwlocCpuInfo.h"
|
||||
#
|
||||
# if HWLOC_API_VERSION < 0x00010b00
|
||||
# define HWLOC_OBJ_NUMANODE HWLOC_OBJ_NODE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -68,9 +68,9 @@ DECL(randomx_program_prologue):
|
|||
#else
|
||||
#include "asm/program_prologue_linux.inc"
|
||||
#endif
|
||||
movapd xmm13, xmmword ptr mantissaMask[rip]
|
||||
movapd xmm14, xmmword ptr exp240[rip]
|
||||
movapd xmm15, xmmword ptr scaleMask[rip]
|
||||
movapd xmm13, xmmword ptr [mantissaMask+rip]
|
||||
movapd xmm14, xmmword ptr [exp240+rip]
|
||||
movapd xmm15, xmmword ptr [scaleMask+rip]
|
||||
jmp DECL(randomx_program_loop_begin)
|
||||
|
||||
.balign 64
|
||||
|
@ -177,26 +177,26 @@ DECL(randomx_sshash_end):
|
|||
DECL(randomx_sshash_init):
|
||||
lea r8, [rbx+1]
|
||||
#include "asm/program_sshash_prefetch.inc"
|
||||
imul r8, qword ptr r0_mul[rip]
|
||||
mov r9, qword ptr r1_add[rip]
|
||||
imul r8, qword ptr [r0_mul+rip]
|
||||
mov r9, qword ptr [r1_add+rip]
|
||||
xor r9, r8
|
||||
mov r10, qword ptr r2_add[rip]
|
||||
mov r10, qword ptr [r2_add+rip]
|
||||
xor r10, r8
|
||||
mov r11, qword ptr r3_add[rip]
|
||||
mov r11, qword ptr [r3_add+rip]
|
||||
xor r11, r8
|
||||
mov r12, qword ptr r4_add[rip]
|
||||
mov r12, qword ptr [r4_add+rip]
|
||||
xor r12, r8
|
||||
mov r13, qword ptr r5_add[rip]
|
||||
mov r13, qword ptr [r5_add+rip]
|
||||
xor r13, r8
|
||||
mov r14, qword ptr r6_add[rip]
|
||||
mov r14, qword ptr [r6_add+rip]
|
||||
xor r14, r8
|
||||
mov r15, qword ptr r7_add[rip]
|
||||
mov r15, qword ptr [r7_add+rip]
|
||||
xor r15, r8
|
||||
jmp DECL(randomx_program_end)
|
||||
|
||||
.balign 64
|
||||
#include "asm/program_sshash_constants.inc"
|
||||
|
||||
|
||||
.balign 64
|
||||
DECL(randomx_program_end):
|
||||
nop
|
||||
|
|
|
@ -26,80 +26,33 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "virtual_memory.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#ifdef __APPLE__
|
||||
#include <mach/vm_statistics.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#ifndef MAP_ANONYMOUS
|
||||
#define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
std::string getErrorMessage(const char* function) {
|
||||
LPSTR messageBuffer = nullptr;
|
||||
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
|
||||
std::string message(messageBuffer, size);
|
||||
LocalFree(messageBuffer);
|
||||
return std::string(function) + std::string(": ") + message;
|
||||
}
|
||||
#endif
|
||||
#include "crypto/common/VirtualMemory.h"
|
||||
#include "virtual_memory.hpp"
|
||||
|
||||
|
||||
void* allocExecutableMemory(std::size_t bytes) {
|
||||
void* mem;
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
mem = VirtualAlloc(nullptr, bytes, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
if (mem == nullptr)
|
||||
throw std::runtime_error(getErrorMessage("allocExecutableMemory - VirtualAlloc"));
|
||||
#else
|
||||
mem = mmap(nullptr, bytes, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||
if (mem == MAP_FAILED)
|
||||
throw std::runtime_error("allocExecutableMemory - mmap failed");
|
||||
#endif
|
||||
return mem;
|
||||
void *mem = xmrig::VirtualMemory::allocateExecutableMemory(bytes);
|
||||
if (mem == nullptr) {
|
||||
throw std::runtime_error("Failed to allocate executable memory");
|
||||
}
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
constexpr std::size_t align(std::size_t pos, std::size_t align) {
|
||||
return ((pos - 1) / align + 1) * align;
|
||||
}
|
||||
|
||||
void* allocLargePagesMemory(std::size_t bytes) {
|
||||
void* mem;
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
auto pageMinimum = GetLargePageMinimum();
|
||||
if (pageMinimum > 0)
|
||||
mem = VirtualAlloc(NULL, align(bytes, pageMinimum), MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE);
|
||||
else
|
||||
throw std::runtime_error("allocLargePagesMemory - Large pages are not supported");
|
||||
if (mem == nullptr)
|
||||
throw std::runtime_error(getErrorMessage("allocLargePagesMemory - VirtualAlloc"));
|
||||
#else
|
||||
#ifdef __APPLE__
|
||||
mem = mmap(nullptr, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0);
|
||||
#elif defined(__FreeBSD__)
|
||||
mem = mmap(nullptr, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER, -1, 0);
|
||||
#else
|
||||
mem = mmap(nullptr, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, -1, 0);
|
||||
#endif
|
||||
if (mem == MAP_FAILED)
|
||||
throw std::runtime_error("allocLargePagesMemory - mmap failed");
|
||||
#endif
|
||||
return mem;
|
||||
void *mem = xmrig::VirtualMemory::allocateLargePagesMemory(bytes);
|
||||
if (mem == nullptr) {
|
||||
throw std::runtime_error("Failed to allocate large pages memory");
|
||||
}
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
|
||||
void freePagedMemory(void* ptr, std::size_t bytes) {
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
VirtualFree(ptr, 0, MEM_RELEASE);
|
||||
#else
|
||||
munmap(ptr, bytes);
|
||||
#endif
|
||||
xmrig::VirtualMemory::freeLargePagesMemory(ptr, bytes);
|
||||
}
|
||||
|
|
|
@ -26,8 +26,8 @@
|
|||
|
||||
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_HWLOC
|
||||
|
@ -43,6 +43,7 @@
|
|||
#include "base/tools/Buffer.h"
|
||||
#include "base/tools/Chrono.h"
|
||||
#include "crypto/rx/Rx.h"
|
||||
#include "crypto/rx/RxAlgo.h"
|
||||
#include "crypto/rx/RxCache.h"
|
||||
#include "crypto/rx/RxDataset.h"
|
||||
|
||||
|
@ -50,15 +51,57 @@
|
|||
namespace xmrig {
|
||||
|
||||
|
||||
static const char *tag = BLUE_BG(WHITE_BOLD_S " rx ") " ";
|
||||
class RxPrivate;
|
||||
|
||||
|
||||
static const char *tag = BLUE_BG(WHITE_BOLD_S " rx ") " ";
|
||||
static RxPrivate *d_ptr = nullptr;
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_HWLOC
|
||||
static void bindToNUMANode(uint32_t nodeId)
|
||||
{
|
||||
hwloc_topology_t topology;
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_load(topology);
|
||||
|
||||
hwloc_obj_t node = hwloc_get_numanode_obj_by_os_index(topology, nodeId);
|
||||
if (node) {
|
||||
if (HwlocCpuInfo::has(HwlocCpuInfo::SET_THISTHREAD_MEMBIND)) {
|
||||
# if HWLOC_API_VERSION >= 0x20000
|
||||
hwloc_set_membind(topology, node->nodeset, HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_THREAD | HWLOC_MEMBIND_BYNODESET);
|
||||
# else
|
||||
hwloc_set_membind_nodeset(topology, node->nodeset, HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_THREAD);
|
||||
# endif
|
||||
}
|
||||
|
||||
Platform::setThreadAffinity(static_cast<uint64_t>(hwloc_bitmap_first(node->cpuset)));
|
||||
}
|
||||
|
||||
hwloc_topology_destroy(topology);
|
||||
}
|
||||
#else
|
||||
inline static void bindToNUMANode(uint32_t) {}
|
||||
#endif
|
||||
|
||||
|
||||
class RxPrivate
|
||||
{
|
||||
public:
|
||||
inline RxPrivate()
|
||||
inline RxPrivate() :
|
||||
m_seed()
|
||||
{
|
||||
uv_mutex_init(&mutex);
|
||||
# ifdef XMRIG_FEATURE_HWLOC
|
||||
if (Cpu::info()->nodes() > 1) {
|
||||
for (uint32_t nodeId : HwlocCpuInfo::nodeIndexes()) {
|
||||
datasets.insert({ nodeId, nullptr });
|
||||
}
|
||||
}
|
||||
else
|
||||
# endif
|
||||
{
|
||||
datasets.insert({ 0, nullptr });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -69,41 +112,22 @@ public:
|
|||
}
|
||||
|
||||
datasets.clear();
|
||||
|
||||
uv_mutex_destroy(&mutex);
|
||||
}
|
||||
|
||||
|
||||
inline void lock() { uv_mutex_lock(&mutex); }
|
||||
inline void unlock() { uv_mutex_unlock(&mutex); }
|
||||
inline bool isNUMA() const { return m_numa; }
|
||||
inline const Algorithm &algorithm() const { return m_algorithm; }
|
||||
inline const uint8_t *seed() const { return m_seed; }
|
||||
inline size_t count() const { return isNUMA() ? datasets.size() : 1; }
|
||||
|
||||
|
||||
static void allocate(RxPrivate *self, uint32_t nodeId)
|
||||
static void allocate(uint32_t nodeId)
|
||||
{
|
||||
const uint64_t ts = Chrono::steadyMSecs();
|
||||
|
||||
# ifdef XMRIG_FEATURE_HWLOC
|
||||
if (self->numa) {
|
||||
hwloc_topology_t topology;
|
||||
hwloc_topology_init(&topology);
|
||||
hwloc_topology_load(topology);
|
||||
|
||||
hwloc_obj_t node = hwloc_get_numanode_obj_by_os_index(topology, nodeId);
|
||||
if (node) {
|
||||
if (HwlocCpuInfo::has(HwlocCpuInfo::SET_THISTHREAD_MEMBIND)) {
|
||||
# if HWLOC_API_VERSION >= 0x20000
|
||||
hwloc_set_membind(topology, node->nodeset, HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_THREAD | HWLOC_MEMBIND_BYNODESET);
|
||||
# else
|
||||
hwloc_set_membind_nodeset(topology, node->nodeset, HWLOC_MEMBIND_BIND, HWLOC_MEMBIND_THREAD);
|
||||
# endif
|
||||
}
|
||||
|
||||
Platform::setThreadAffinity(static_cast<uint64_t>(hwloc_bitmap_first(node->cpuset)));
|
||||
}
|
||||
|
||||
hwloc_topology_destroy(topology);
|
||||
if (d_ptr->isNUMA()) {
|
||||
bindToNUMANode(nodeId);
|
||||
}
|
||||
# endif
|
||||
|
||||
LOG_INFO("%s" CYAN_BOLD("#%u") MAGENTA_BOLD(" allocate") CYAN_BOLD(" %zu MB") BLACK_BOLD(" (%zu+%zu) for RandomX dataset & cache"),
|
||||
tag,
|
||||
|
@ -113,8 +137,8 @@ public:
|
|||
RxCache::size() / 1024 / 1024
|
||||
);
|
||||
|
||||
RxDataset *dataset = new RxDataset(self->hugePages);
|
||||
self->datasets[nodeId] = dataset;
|
||||
RxDataset *dataset = new RxDataset(d_ptr->m_hugePages);
|
||||
d_ptr->datasets[nodeId] = dataset;
|
||||
|
||||
if (dataset->get() != nullptr) {
|
||||
const auto hugePages = dataset->hugePages();
|
||||
|
@ -137,43 +161,99 @@ public:
|
|||
}
|
||||
|
||||
|
||||
bool hugePages = true;
|
||||
bool numa = true;
|
||||
static void initDataset(uint32_t nodeId, uint32_t threads)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(d_ptr->mutex);
|
||||
|
||||
const uint64_t ts = Chrono::steadyMSecs();
|
||||
|
||||
d_ptr->getOrAllocate(nodeId)->init(d_ptr->seed(), threads);
|
||||
d_ptr->m_ready++;
|
||||
|
||||
LOG_INFO("%s" CYAN_BOLD("#%u") GREEN(" init done") BLACK_BOLD(" (%" PRIu64 " ms)"), tag, nodeId, Chrono::steadyMSecs() - ts);
|
||||
}
|
||||
|
||||
|
||||
inline RxDataset *getOrAllocate(uint32_t nodeId)
|
||||
{
|
||||
RxDataset *dataset = datasets.at(nodeId);
|
||||
|
||||
if (dataset == nullptr) {
|
||||
# ifdef XMRIG_FEATURE_HWLOC
|
||||
if (d_ptr->isNUMA()) {
|
||||
std::thread thread(allocate, nodeId);
|
||||
thread.join();
|
||||
} else
|
||||
# endif
|
||||
{
|
||||
allocate(nodeId);
|
||||
}
|
||||
|
||||
dataset = datasets.at(nodeId);
|
||||
}
|
||||
|
||||
return dataset;
|
||||
}
|
||||
|
||||
|
||||
inline void setState(const Job &job, bool hugePages, bool numa)
|
||||
{
|
||||
if (m_algorithm != job.algorithm()) {
|
||||
m_algorithm = RxAlgo::apply(job.algorithm());
|
||||
}
|
||||
|
||||
m_ready = 0;
|
||||
m_numa = numa && Cpu::info()->nodes() > 1;
|
||||
m_hugePages = hugePages;
|
||||
|
||||
memcpy(m_seed, job.seedHash(), sizeof(m_seed));
|
||||
}
|
||||
|
||||
|
||||
inline bool isReady(const Job &job)
|
||||
{
|
||||
return m_ready == count() && m_algorithm == job.algorithm() && memcmp(m_seed, job.seedHash(), sizeof(m_seed)) == 0;
|
||||
}
|
||||
|
||||
|
||||
std::map<uint32_t, RxDataset *> datasets;
|
||||
uv_mutex_t mutex;
|
||||
std::mutex mutex;
|
||||
|
||||
private:
|
||||
bool m_hugePages = true;
|
||||
bool m_numa = true;
|
||||
Algorithm m_algorithm;
|
||||
size_t m_ready = 0;
|
||||
uint8_t m_seed[32];
|
||||
};
|
||||
|
||||
|
||||
static RxPrivate *d_ptr = new RxPrivate();
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
bool xmrig::Rx::isReady(const Job &job, uint32_t nodeId)
|
||||
bool xmrig::Rx::isReady(const Job &job)
|
||||
{
|
||||
d_ptr->lock();
|
||||
const bool rc = isReady(job.seedHash(), job.algorithm(), d_ptr->numa ? nodeId : 0);
|
||||
d_ptr->unlock();
|
||||
std::lock_guard<std::mutex> lock(d_ptr->mutex);
|
||||
|
||||
return rc;
|
||||
return d_ptr->isReady(job);
|
||||
}
|
||||
|
||||
|
||||
xmrig::RxDataset *xmrig::Rx::dataset(uint32_t nodeId)
|
||||
xmrig::RxDataset *xmrig::Rx::dataset(const Job &job, uint32_t nodeId)
|
||||
{
|
||||
d_ptr->lock();
|
||||
RxDataset *dataset = d_ptr->datasets[d_ptr->numa ? nodeId : 0];
|
||||
d_ptr->unlock();
|
||||
std::lock_guard<std::mutex> lock(d_ptr->mutex);
|
||||
if (!d_ptr->isReady(job)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return dataset;
|
||||
return d_ptr->datasets.at(d_ptr->isNUMA() ? nodeId : 0);
|
||||
}
|
||||
|
||||
|
||||
std::pair<size_t, size_t> xmrig::Rx::hugePages()
|
||||
{
|
||||
std::pair<size_t, size_t> pages(0, 0);
|
||||
d_ptr->lock();
|
||||
std::lock_guard<std::mutex> lock(d_ptr->mutex);
|
||||
|
||||
for (auto const &item : d_ptr->datasets) {
|
||||
if (!item.second) {
|
||||
|
@ -185,116 +265,59 @@ std::pair<size_t, size_t> xmrig::Rx::hugePages()
|
|||
pages.second += p.second;
|
||||
}
|
||||
|
||||
d_ptr->unlock();
|
||||
|
||||
return pages;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Rx::destroy()
|
||||
{
|
||||
delete d_ptr;
|
||||
|
||||
d_ptr = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Rx::init()
|
||||
{
|
||||
d_ptr = new RxPrivate();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Rx::init(const Job &job, int initThreads, bool hugePages, bool numa)
|
||||
{
|
||||
if (job.algorithm().family() != Algorithm::RANDOM_X) {
|
||||
return;
|
||||
}
|
||||
|
||||
d_ptr->lock();
|
||||
|
||||
size_t ready = 0;
|
||||
|
||||
for (auto const &item : d_ptr->datasets) {
|
||||
if (isReady(job.seedHash(), job.algorithm(), item.first)) {
|
||||
ready++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!d_ptr->datasets.empty() && ready == d_ptr->datasets.size()) {
|
||||
d_ptr->unlock();
|
||||
std::lock_guard<std::mutex> lock(d_ptr->mutex);
|
||||
|
||||
if (d_ptr->isReady(job)) {
|
||||
return;
|
||||
}
|
||||
|
||||
d_ptr->hugePages = hugePages;
|
||||
d_ptr->numa = numa && Cpu::info()->nodes() > 1;
|
||||
const uint32_t threads = initThreads < 1 ? static_cast<uint32_t>(Cpu::info()->threads())
|
||||
: static_cast<uint32_t>(initThreads);
|
||||
d_ptr->setState(job, hugePages, numa);
|
||||
const uint32_t threads = initThreads < 1 ? static_cast<uint32_t>(Cpu::info()->threads()) : static_cast<uint32_t>(initThreads);
|
||||
const String buf = Buffer::toHex(job.seedHash(), 8);
|
||||
|
||||
LOG_INFO("%s" MAGENTA_BOLD("init dataset%s") " algo " WHITE_BOLD("%s (") CYAN_BOLD("%u") WHITE_BOLD(" threads)") BLACK_BOLD(" seed %s..."),
|
||||
tag,
|
||||
d_ptr->count() > 1 ? "s" : "",
|
||||
job.algorithm().shortName(),
|
||||
threads,
|
||||
buf.data()
|
||||
);
|
||||
|
||||
# ifdef XMRIG_FEATURE_HWLOC
|
||||
if (d_ptr->numa) {
|
||||
for (uint32_t nodeId : HwlocCpuInfo::nodeIndexes()) {
|
||||
std::thread thread(initDataset, nodeId, job.seedHash(), job.algorithm(), threads);
|
||||
if (d_ptr->isNUMA()) {
|
||||
for (auto const &item : d_ptr->datasets) {
|
||||
std::thread thread(RxPrivate::initDataset, item.first, threads);
|
||||
thread.detach();
|
||||
}
|
||||
}
|
||||
else
|
||||
# endif
|
||||
{
|
||||
std::thread thread(initDataset, 0, job.seedHash(), job.algorithm(), threads);
|
||||
std::thread thread(RxPrivate::initDataset, 0, threads);
|
||||
thread.detach();
|
||||
}
|
||||
|
||||
d_ptr->unlock();
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Rx::stop()
|
||||
{
|
||||
delete d_ptr;
|
||||
|
||||
d_ptr = nullptr;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::Rx::isReady(const uint8_t *seed, const Algorithm &algorithm, uint32_t nodeId)
|
||||
{
|
||||
return !d_ptr->datasets.empty() && d_ptr->datasets[nodeId] != nullptr && d_ptr->datasets[nodeId]->isReady(seed, algorithm);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::Rx::initDataset(uint32_t nodeId, const uint8_t *seed, const Algorithm &algorithm, uint32_t threads)
|
||||
{
|
||||
d_ptr->lock();
|
||||
|
||||
RxDataset *dataset = d_ptr->datasets[nodeId];
|
||||
|
||||
if (!dataset) {
|
||||
# ifdef XMRIG_FEATURE_HWLOC
|
||||
if (d_ptr->numa) {
|
||||
std::thread thread(RxPrivate::allocate, d_ptr, nodeId);
|
||||
thread.join();
|
||||
} else
|
||||
# endif
|
||||
{
|
||||
RxPrivate::allocate(d_ptr, nodeId);
|
||||
}
|
||||
|
||||
dataset = d_ptr->datasets[nodeId];
|
||||
}
|
||||
|
||||
if (!dataset->isReady(seed, algorithm)) {
|
||||
const uint64_t ts = Chrono::steadyMSecs();
|
||||
|
||||
if (dataset->get() != nullptr) {
|
||||
LOG_INFO("%s" CYAN_BOLD("#%u") MAGENTA_BOLD(" init dataset") " algo " WHITE_BOLD("%s (") CYAN_BOLD("%u") WHITE_BOLD(" threads)") BLACK_BOLD(" seed %s..."),
|
||||
tag,
|
||||
nodeId,
|
||||
algorithm.shortName(),
|
||||
threads,
|
||||
Buffer::toHex(seed, 8).data()
|
||||
);
|
||||
}
|
||||
else {
|
||||
LOG_INFO("%s" CYAN_BOLD("#%u") MAGENTA_BOLD(" init cache") " algo " WHITE_BOLD("%s") BLACK_BOLD(" seed %s..."),
|
||||
tag,
|
||||
nodeId,
|
||||
algorithm.shortName(),
|
||||
Buffer::toHex(seed, 8).data()
|
||||
);
|
||||
}
|
||||
|
||||
dataset->init(seed, algorithm, threads);
|
||||
|
||||
LOG_INFO("%s" CYAN_BOLD("#%u") GREEN(" init done") BLACK_BOLD(" (%" PRIu64 " ms)"), tag, nodeId, Chrono::steadyMSecs() - ts);
|
||||
}
|
||||
|
||||
d_ptr->unlock();
|
||||
}
|
||||
|
|
|
@ -44,15 +44,12 @@ class Job;
|
|||
class Rx
|
||||
{
|
||||
public:
|
||||
static bool isReady(const Job &job, uint32_t nodeId);
|
||||
static RxDataset *dataset(uint32_t nodeId);
|
||||
static bool isReady(const Job &job);
|
||||
static RxDataset *dataset(const Job &job, uint32_t nodeId);
|
||||
static std::pair<size_t, size_t> hugePages();
|
||||
static void destroy();
|
||||
static void init();
|
||||
static void init(const Job &job, int initThreads, bool hugePages, bool numa);
|
||||
static void stop();
|
||||
|
||||
private:
|
||||
static bool isReady(const uint8_t *seed, const Algorithm &algorithm, uint32_t nodeId);
|
||||
static void initDataset(uint32_t nodeId, const uint8_t *seed, const Algorithm &algorithm, uint32_t threads);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -53,11 +53,12 @@ public:
|
|||
inline randomx_cache *get() const { return m_cache; }
|
||||
|
||||
bool init(const void *seed);
|
||||
bool isReady(const void *seed) const;
|
||||
|
||||
static inline constexpr size_t size() { return RANDOMX_CACHE_MAX_SIZE; }
|
||||
|
||||
private:
|
||||
bool isReady(const void *seed) const;
|
||||
|
||||
int m_flags = 0;
|
||||
randomx_cache *m_cache = nullptr;
|
||||
uint8_t m_seed[32];
|
||||
|
|
|
@ -64,16 +64,8 @@ xmrig::RxDataset::~RxDataset()
|
|||
}
|
||||
|
||||
|
||||
bool xmrig::RxDataset::init(const void *seed, const Algorithm &algorithm, uint32_t numThreads)
|
||||
bool xmrig::RxDataset::init(const void *seed, uint32_t numThreads)
|
||||
{
|
||||
if (isReady(seed, algorithm)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_algorithm != algorithm) {
|
||||
m_algorithm = RxAlgo::apply(algorithm);
|
||||
}
|
||||
|
||||
cache()->init(seed);
|
||||
|
||||
if (!get()) {
|
||||
|
@ -104,12 +96,6 @@ bool xmrig::RxDataset::init(const void *seed, const Algorithm &algorithm, uint32
|
|||
}
|
||||
|
||||
|
||||
bool xmrig::RxDataset::isReady(const void *seed, const Algorithm &algorithm) const
|
||||
{
|
||||
return algorithm == m_algorithm && cache()->isReady(seed);
|
||||
}
|
||||
|
||||
|
||||
std::pair<size_t, size_t> xmrig::RxDataset::hugePages() const
|
||||
{
|
||||
constexpr size_t twoMiB = 2u * 1024u * 1024u;
|
||||
|
|
|
@ -52,8 +52,7 @@ public:
|
|||
inline randomx_dataset *get() const { return m_dataset; }
|
||||
inline RxCache *cache() const { return m_cache; }
|
||||
|
||||
bool init(const void *seed, const Algorithm &algorithm, uint32_t numThreads);
|
||||
bool isReady(const void *seed, const Algorithm &algorithm) const;
|
||||
bool init(const void *seed, uint32_t numThreads);
|
||||
std::pair<size_t, size_t> hugePages() const;
|
||||
|
||||
static inline constexpr size_t size() { return RANDOMX_DATASET_MAX_SIZE; }
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#define APP_ID "xmrig"
|
||||
#define APP_NAME "XMRig"
|
||||
#define APP_DESC "XMRig CPU miner"
|
||||
#define APP_VERSION "2.99.3-beta"
|
||||
#define APP_VERSION "2.99.4-evo"
|
||||
#define APP_DOMAIN "xmrig.com"
|
||||
#define APP_SITE "www.xmrig.com"
|
||||
#define APP_COPYRIGHT "Copyright (C) 2016-2019 xmrig.com"
|
||||
|
@ -36,7 +36,7 @@
|
|||
|
||||
#define APP_VER_MAJOR 2
|
||||
#define APP_VER_MINOR 99
|
||||
#define APP_VER_PATCH 3
|
||||
#define APP_VER_PATCH 4
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# if (_MSC_VER >= 1920)
|
||||
|
|
Loading…
Reference in a new issue