mirror of
https://github.com/xmrig/xmrig.git
synced 2024-11-18 10:01:06 +00:00
Merge branch 'feature-hugepages-pool' into evo
This commit is contained in:
commit
119e7ea7bf
33 changed files with 811 additions and 185 deletions
|
@ -55,6 +55,7 @@ set(HEADERS
|
|||
)
|
||||
|
||||
set(HEADERS_CRYPTO
|
||||
src/backend/common/interfaces/IMemoryPool.h
|
||||
src/crypto/cn/asm/CryptonightR_template.h
|
||||
src/crypto/cn/c_blake256.h
|
||||
src/crypto/cn/c_groestl.h
|
||||
|
@ -73,6 +74,7 @@ set(HEADERS_CRYPTO
|
|||
src/crypto/common/Algorithm.h
|
||||
src/crypto/common/Coin.h
|
||||
src/crypto/common/keccak.h
|
||||
src/crypto/common/MemoryPool.h
|
||||
src/crypto/common/Nonce.h
|
||||
src/crypto/common/portable/mm_malloc.h
|
||||
src/crypto/common/VirtualMemory.h
|
||||
|
@ -111,10 +113,22 @@ set(SOURCES_CRYPTO
|
|||
src/crypto/common/Algorithm.cpp
|
||||
src/crypto/common/Coin.cpp
|
||||
src/crypto/common/keccak.cpp
|
||||
src/crypto/common/MemoryPool.cpp
|
||||
src/crypto/common/Nonce.cpp
|
||||
src/crypto/common/VirtualMemory.cpp
|
||||
)
|
||||
|
||||
if (WITH_HWLOC)
|
||||
list(APPEND HEADERS_CRYPTO
|
||||
src/crypto/common/NUMAMemoryPool.h
|
||||
)
|
||||
|
||||
list(APPEND SOURCES_CRYPTO
|
||||
src/crypto/common/NUMAMemoryPool.cpp
|
||||
src/crypto/common/VirtualMemory_hwloc.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
set(SOURCES_OS
|
||||
"${SOURCES_OS}"
|
||||
|
|
|
@ -70,7 +70,7 @@ if (WITH_RANDOMX)
|
|||
endif()
|
||||
|
||||
if (WITH_HWLOC)
|
||||
list(APPEND SOURCES_CRYPTO
|
||||
list(APPEND HEADERS_CRYPTO
|
||||
src/crypto/rx/RxNUMAStorage.h
|
||||
)
|
||||
|
||||
|
|
|
@ -97,3 +97,6 @@ Allow override automatically detected Argon2 implementation, this option added m
|
|||
|
||||
#### `max-threads-hint` (since v4.2.0)
|
||||
Maximum CPU threads count (in percentage) hint for autoconfig. [CPU_MAX_USAGE.md](CPU_MAX_USAGE.md)
|
||||
|
||||
#### `memory-pool` (since v4.3.0)
|
||||
Use continuous, persistent memory block for mining threads, useful for preserve huge pages allocation while algorithm swithing. Default value `false` (feature disabled) or `true` or specific count of 2 MB huge pages.
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include "core/config/Config.h"
|
||||
#include "core/Controller.h"
|
||||
#include "core/Miner.h"
|
||||
#include "crypto/common/VirtualMemory.h"
|
||||
#include "net/Network.h"
|
||||
#include "Summary.h"
|
||||
#include "version.h"
|
||||
|
@ -80,8 +79,6 @@ int xmrig::App::exec()
|
|||
m_console = new Console(this);
|
||||
}
|
||||
|
||||
VirtualMemory::init(m_controller->config()->cpu().isHugePages());
|
||||
|
||||
Summary::print(m_controller);
|
||||
|
||||
if (m_controller->config()->isDryRun()) {
|
||||
|
|
|
@ -34,8 +34,7 @@ xmrig::Worker::Worker(size_t id, int64_t affinity, int priority) :
|
|||
m_affinity(affinity),
|
||||
m_id(id),
|
||||
m_hashCount(0),
|
||||
m_timestamp(0),
|
||||
m_count(0)
|
||||
m_timestamp(0)
|
||||
{
|
||||
m_node = VirtualMemory::bindToNUMANode(affinity);
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ protected:
|
|||
std::atomic<uint64_t> m_hashCount;
|
||||
std::atomic<uint64_t> m_timestamp;
|
||||
uint32_t m_node = 0;
|
||||
uint64_t m_count;
|
||||
uint64_t m_count = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
53
src/backend/common/interfaces/IMemoryPool.h
Normal file
53
src/backend/common/interfaces/IMemoryPool.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_IMEMORYPOOL_H
|
||||
#define XMRIG_IMEMORYPOOL_H
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IMemoryPool
|
||||
{
|
||||
public:
|
||||
virtual ~IMemoryPool() = default;
|
||||
|
||||
virtual bool isHugePages(uint32_t node) const = 0;
|
||||
virtual uint8_t *get(size_t size, uint32_t node) = 0;
|
||||
virtual void release(uint32_t node) = 0;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
|
||||
#endif /* XMRIG_IMEMORYPOOL_H */
|
|
@ -36,6 +36,7 @@ static const char *kEnabled = "enabled";
|
|||
static const char *kHugePages = "huge-pages";
|
||||
static const char *kHwAes = "hw-aes";
|
||||
static const char *kMaxThreadsHint = "max-threads-hint";
|
||||
static const char *kMemoryPool = "memory-pool";
|
||||
static const char *kPriority = "priority";
|
||||
|
||||
#ifdef XMRIG_FEATURE_ASM
|
||||
|
@ -90,6 +91,7 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const
|
|||
obj.AddMember(StringRef(kHugePages), m_hugePages, allocator);
|
||||
obj.AddMember(StringRef(kHwAes), m_aes == AES_AUTO ? Value(kNullType) : Value(m_aes == AES_HW), allocator);
|
||||
obj.AddMember(StringRef(kPriority), priority() != -1 ? Value(priority()) : Value(kNullType), allocator);
|
||||
obj.AddMember(StringRef(kMemoryPool), m_memoryPool < 1 ? Value(m_memoryPool < 0) : Value(m_memoryPool), allocator);
|
||||
|
||||
if (m_threads.isEmpty()) {
|
||||
obj.AddMember(StringRef(kMaxThreadsHint), m_limit, allocator);
|
||||
|
@ -109,6 +111,12 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const
|
|||
}
|
||||
|
||||
|
||||
size_t xmrig::CpuConfig::memPoolSize() const
|
||||
{
|
||||
return m_memoryPool < 0 ? Cpu::info()->threads() : m_memoryPool;
|
||||
}
|
||||
|
||||
|
||||
std::vector<xmrig::CpuLaunchData> xmrig::CpuConfig::get(const Miner *miner, const Algorithm &algorithm) const
|
||||
{
|
||||
std::vector<CpuLaunchData> out;
|
||||
|
@ -137,6 +145,7 @@ void xmrig::CpuConfig::read(const rapidjson::Value &value, uint32_t version)
|
|||
|
||||
setAesMode(Json::getValue(value, kHwAes));
|
||||
setPriority(Json::getInt(value, kPriority, -1));
|
||||
setMemoryPool(Json::getValue(value, kMemoryPool));
|
||||
|
||||
# ifdef XMRIG_FEATURE_ASM
|
||||
m_assembly = Json::getValue(value, kAsm);
|
||||
|
@ -205,12 +214,23 @@ void xmrig::CpuConfig::generateArgon2()
|
|||
}
|
||||
|
||||
|
||||
void xmrig::CpuConfig::setAesMode(const rapidjson::Value &aesMode)
|
||||
void xmrig::CpuConfig::setAesMode(const rapidjson::Value &value)
|
||||
{
|
||||
if (aesMode.IsBool()) {
|
||||
m_aes = aesMode.GetBool() ? AES_HW : AES_SOFT;
|
||||
if (value.IsBool()) {
|
||||
m_aes = value.GetBool() ? AES_HW : AES_SOFT;
|
||||
}
|
||||
else {
|
||||
m_aes = AES_AUTO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::CpuConfig::setMemoryPool(const rapidjson::Value &value)
|
||||
{
|
||||
if (value.IsBool()) {
|
||||
m_memoryPool = value.GetBool() ? -1 : 0;
|
||||
}
|
||||
else if (value.IsInt()) {
|
||||
m_memoryPool = value.GetInt();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
|
||||
bool isHwAES() const;
|
||||
rapidjson::Value toJSON(rapidjson::Document &doc) const;
|
||||
size_t memPoolSize() const;
|
||||
std::vector<CpuLaunchData> get(const Miner *miner, const Algorithm &algorithm) const;
|
||||
void read(const rapidjson::Value &value, uint32_t version);
|
||||
|
||||
|
@ -62,7 +63,8 @@ public:
|
|||
private:
|
||||
void generate();
|
||||
void generateArgon2();
|
||||
void setAesMode(const rapidjson::Value &aesMode);
|
||||
void setAesMode(const rapidjson::Value &value);
|
||||
void setMemoryPool(const rapidjson::Value &value);
|
||||
|
||||
inline void setPriority(int priority) { m_priority = (priority >= -1 && priority <= 5) ? priority : -1; }
|
||||
|
||||
|
@ -71,6 +73,7 @@ private:
|
|||
bool m_enabled = true;
|
||||
bool m_hugePages = true;
|
||||
bool m_shouldSave = false;
|
||||
int m_memoryPool = 0;
|
||||
int m_priority = -1;
|
||||
String m_argon2Impl;
|
||||
Threads<CpuThreads> m_threads;
|
||||
|
|
|
@ -62,7 +62,7 @@ xmrig::CpuWorker<N>::CpuWorker(size_t id, const CpuLaunchData &data) :
|
|||
m_miner(data.miner),
|
||||
m_ctx()
|
||||
{
|
||||
m_memory = new VirtualMemory(m_algorithm.l3() * N, data.hugePages);
|
||||
m_memory = new VirtualMemory(m_algorithm.l3() * N, data.hugePages, true, m_node);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -98,7 +98,14 @@ elseif (APPLE)
|
|||
else()
|
||||
set(SOURCES_OS
|
||||
src/base/io/json/Json_unix.cpp
|
||||
src/base/kernel//Platform_unix.cpp
|
||||
src/base/kernel/Platform_unix.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
if (WITH_HWLOC)
|
||||
list(APPEND SOURCES_OS
|
||||
src/base/kernel/Platform_hwloc.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -23,7 +23,10 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include "base/kernel/Platform.h"
|
||||
|
||||
|
||||
#include <cstring>
|
||||
#include <uv.h>
|
||||
|
||||
|
||||
|
@ -33,13 +36,14 @@
|
|||
#endif
|
||||
|
||||
|
||||
#include "Platform.h"
|
||||
namespace xmrig {
|
||||
|
||||
String Platform::m_userAgent;
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::String Platform::m_userAgent;
|
||||
|
||||
|
||||
void Platform::init(const char *userAgent)
|
||||
void xmrig::Platform::init(const char *userAgent)
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_TLS
|
||||
SSL_library_init();
|
||||
|
|
|
@ -26,12 +26,15 @@
|
|||
#define XMRIG_PLATFORM_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
#include "base/tools/String.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class Platform
|
||||
{
|
||||
public:
|
||||
|
@ -56,8 +59,11 @@ public:
|
|||
private:
|
||||
static char *createUserAgent();
|
||||
|
||||
static xmrig::String m_userAgent;
|
||||
static String m_userAgent;
|
||||
};
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
#endif /* XMRIG_PLATFORM_H */
|
||||
|
|
49
src/base/kernel/Platform_hwloc.cpp
Normal file
49
src/base/kernel/Platform_hwloc.cpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "base/kernel/Platform.h"
|
||||
#include "backend/cpu/platform/HwlocCpuInfo.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
|
||||
|
||||
#include <hwloc.h>
|
||||
|
||||
|
||||
bool xmrig::Platform::setThreadAffinity(uint64_t cpu_id)
|
||||
{
|
||||
auto cpu = static_cast<HwlocCpuInfo *>(Cpu::info());
|
||||
hwloc_obj_t pu = hwloc_get_pu_obj_by_os_index(cpu->topology(), static_cast<unsigned>(cpu_id));
|
||||
|
||||
if (pu == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hwloc_set_cpubind(cpu->topology(), pu->cpuset, HWLOC_CPUBIND_THREAD | HWLOC_CPUBIND_STRICT) >= 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return hwloc_set_cpubind(cpu->topology(), pu->cpuset, HWLOC_CPUBIND_THREAD) >= 0;
|
||||
}
|
|
@ -30,7 +30,7 @@
|
|||
#include <uv.h>
|
||||
|
||||
|
||||
#include "Platform.h"
|
||||
#include "base/kernel/Platform.h"
|
||||
#include "version.h"
|
||||
|
||||
#ifdef XMRIG_NVIDIA_PROJECT
|
||||
|
@ -38,7 +38,7 @@
|
|||
#endif
|
||||
|
||||
|
||||
char *Platform::createUserAgent()
|
||||
char *xmrig::Platform::createUserAgent()
|
||||
{
|
||||
constexpr const size_t max = 256;
|
||||
|
||||
|
@ -60,7 +60,8 @@ char *Platform::createUserAgent()
|
|||
}
|
||||
|
||||
|
||||
bool Platform::setThreadAffinity(uint64_t cpu_id)
|
||||
#ifndef XMRIG_FEATURE_HWLOC
|
||||
bool xmrig::Platform::setThreadAffinity(uint64_t cpu_id)
|
||||
{
|
||||
thread_port_t mach_thread;
|
||||
thread_affinity_policy_data_t policy = { static_cast<integer_t>(cpu_id) };
|
||||
|
@ -68,25 +69,26 @@ bool Platform::setThreadAffinity(uint64_t cpu_id)
|
|||
|
||||
return thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&policy, 1) == KERN_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
uint32_t Platform::setTimerResolution(uint32_t resolution)
|
||||
uint32_t xmrig::Platform::setTimerResolution(uint32_t resolution)
|
||||
{
|
||||
return resolution;
|
||||
}
|
||||
|
||||
|
||||
void Platform::restoreTimerResolution()
|
||||
void xmrig::Platform::restoreTimerResolution()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Platform::setProcessPriority(int priority)
|
||||
void xmrig::Platform::setProcessPriority(int priority)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Platform::setThreadPriority(int priority)
|
||||
void xmrig::Platform::setThreadPriority(int priority)
|
||||
{
|
||||
if (priority == -1) {
|
||||
return;
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#include <uv.h>
|
||||
|
||||
|
||||
#include "Platform.h"
|
||||
#include "base/kernel/Platform.h"
|
||||
#include "version.h"
|
||||
|
||||
#ifdef XMRIG_NVIDIA_PROJECT
|
||||
|
@ -52,7 +52,7 @@ typedef cpuset_t cpu_set_t;
|
|||
#endif
|
||||
|
||||
|
||||
char *Platform::createUserAgent()
|
||||
char *xmrig::Platform::createUserAgent()
|
||||
{
|
||||
constexpr const size_t max = 256;
|
||||
|
||||
|
@ -84,7 +84,8 @@ char *Platform::createUserAgent()
|
|||
}
|
||||
|
||||
|
||||
bool Platform::setThreadAffinity(uint64_t cpu_id)
|
||||
#ifndef XMRIG_FEATURE_HWLOC
|
||||
bool xmrig::Platform::setThreadAffinity(uint64_t cpu_id)
|
||||
{
|
||||
cpu_set_t mn;
|
||||
CPU_ZERO(&mn);
|
||||
|
@ -96,25 +97,26 @@ bool Platform::setThreadAffinity(uint64_t cpu_id)
|
|||
return sched_setaffinity(gettid(), sizeof(cpu_set_t), &mn) == 0;
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
uint32_t Platform::setTimerResolution(uint32_t resolution)
|
||||
uint32_t xmrig::Platform::setTimerResolution(uint32_t resolution)
|
||||
{
|
||||
return resolution;
|
||||
}
|
||||
|
||||
|
||||
void Platform::restoreTimerResolution()
|
||||
void xmrig::Platform::restoreTimerResolution()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Platform::setProcessPriority(int priority)
|
||||
void xmrig::Platform::setProcessPriority(int priority)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Platform::setThreadPriority(int priority)
|
||||
void xmrig::Platform::setThreadPriority(int priority)
|
||||
{
|
||||
if (priority == -1) {
|
||||
return;
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
#include <uv.h>
|
||||
|
||||
|
||||
#include "base/kernel/Platform.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "Platform.h"
|
||||
#include "version.h"
|
||||
|
||||
|
||||
|
@ -51,10 +51,10 @@ static inline OSVERSIONINFOEX winOsVersion()
|
|||
|
||||
HMODULE ntdll = GetModuleHandleW(L"ntdll.dll");
|
||||
if (ntdll ) {
|
||||
RtlGetVersionFunction pRtlGetVersion = reinterpret_cast<RtlGetVersionFunction>(GetProcAddress(ntdll, "RtlGetVersion"));
|
||||
auto pRtlGetVersion = reinterpret_cast<RtlGetVersionFunction>(GetProcAddress(ntdll, "RtlGetVersion"));
|
||||
|
||||
if (pRtlGetVersion) {
|
||||
pRtlGetVersion((LPOSVERSIONINFO) &result);
|
||||
pRtlGetVersion(reinterpret_cast<LPOSVERSIONINFO>(&result));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ static inline OSVERSIONINFOEX winOsVersion()
|
|||
}
|
||||
|
||||
|
||||
char *Platform::createUserAgent()
|
||||
char *xmrig::Platform::createUserAgent()
|
||||
{
|
||||
const auto osver = winOsVersion();
|
||||
constexpr const size_t max = 256;
|
||||
|
@ -91,7 +91,8 @@ char *Platform::createUserAgent()
|
|||
}
|
||||
|
||||
|
||||
bool Platform::setThreadAffinity(uint64_t cpu_id)
|
||||
#ifndef XMRIG_FEATURE_HWLOC
|
||||
bool xmrig::Platform::setThreadAffinity(uint64_t cpu_id)
|
||||
{
|
||||
if (cpu_id >= 64) {
|
||||
LOG_ERR("Unable to set affinity. Windows supports only affinity up to 63.");
|
||||
|
@ -99,9 +100,10 @@ bool Platform::setThreadAffinity(uint64_t cpu_id)
|
|||
|
||||
return SetThreadAffinityMask(GetCurrentThread(), 1ULL << cpu_id) != 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
uint32_t Platform::setTimerResolution(uint32_t resolution)
|
||||
uint32_t xmrig::Platform::setTimerResolution(uint32_t resolution)
|
||||
{
|
||||
# ifdef XMRIG_AMD_PROJECT
|
||||
TIMECAPS tc;
|
||||
|
@ -119,7 +121,7 @@ uint32_t Platform::setTimerResolution(uint32_t resolution)
|
|||
}
|
||||
|
||||
|
||||
void Platform::restoreTimerResolution()
|
||||
void xmrig::Platform::restoreTimerResolution()
|
||||
{
|
||||
# ifdef XMRIG_AMD_PROJECT
|
||||
if (timerResolution) {
|
||||
|
@ -129,7 +131,7 @@ void Platform::restoreTimerResolution()
|
|||
}
|
||||
|
||||
|
||||
void Platform::setProcessPriority(int priority)
|
||||
void xmrig::Platform::setProcessPriority(int priority)
|
||||
{
|
||||
if (priority == -1) {
|
||||
return;
|
||||
|
@ -166,7 +168,7 @@ void Platform::setProcessPriority(int priority)
|
|||
}
|
||||
|
||||
|
||||
void Platform::setThreadPriority(int priority)
|
||||
void xmrig::Platform::setThreadPriority(int priority)
|
||||
{
|
||||
if (priority == -1) {
|
||||
return;
|
||||
|
|
|
@ -908,8 +908,14 @@ void xmrig::Client::onConnect(uv_connect_t *req, int status)
|
|||
LOG_ERR("[%s] connect error: \"%s\"", client->url(), uv_strerror(status));
|
||||
}
|
||||
|
||||
if (client->state() == ReconnectingState) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (client->state() != ConnectingState) {
|
||||
if (!client->isQuiet()) {
|
||||
LOG_ERR("[%s] connect error: \"invalid state: %d\"", client->url(), client->state());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
"huge-pages": true,
|
||||
"hw-aes": null,
|
||||
"priority": null,
|
||||
"memory-pool": false,
|
||||
"max-threads-hint": 100,
|
||||
"asm": true,
|
||||
"argon2-impl": null,
|
||||
|
|
|
@ -23,15 +23,17 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "core/Controller.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "core/config/Config.h"
|
||||
#include "core/Miner.h"
|
||||
#include "crypto/common/VirtualMemory.h"
|
||||
#include "net/Network.h"
|
||||
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
xmrig::Controller::Controller(Process *process) :
|
||||
Base(process)
|
||||
{
|
||||
|
@ -41,6 +43,8 @@ xmrig::Controller::Controller(Process *process) :
|
|||
xmrig::Controller::~Controller()
|
||||
{
|
||||
delete m_network;
|
||||
|
||||
VirtualMemory::destroy();
|
||||
}
|
||||
|
||||
|
||||
|
@ -48,7 +52,10 @@ int xmrig::Controller::init()
|
|||
{
|
||||
Base::init();
|
||||
|
||||
VirtualMemory::init(config()->cpu().memPoolSize(), config()->cpu().isHugePages());
|
||||
|
||||
m_network = new Network(this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,11 +26,12 @@
|
|||
#define XMRIG_CONFIG_H
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
#include "backend/cpu/CpuConfig.h"
|
||||
#include "base/kernel/config/BaseConfig.h"
|
||||
#include "base/tools/Object.h"
|
||||
#include "rapidjson/fwd.h"
|
||||
|
||||
|
||||
|
@ -46,6 +47,8 @@ class OclConfig;
|
|||
class Config : public BaseConfig
|
||||
{
|
||||
public:
|
||||
XMRIG_DISABLE_COPY_MOVE(Config);
|
||||
|
||||
Config();
|
||||
~Config() override;
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ R"===(
|
|||
"huge-pages": true,
|
||||
"hw-aes": null,
|
||||
"priority": null,
|
||||
"memory-pool": false,
|
||||
"max-threads-hint": 100,
|
||||
"asm": true,
|
||||
"argon2-impl": null,
|
||||
|
|
95
src/crypto/common/MemoryPool.cpp
Normal file
95
src/crypto/common/MemoryPool.cpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "crypto/common/MemoryPool.h"
|
||||
#include "crypto/common/VirtualMemory.h"
|
||||
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
constexpr size_t pageSize = 2 * 1024 * 1024;
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::MemoryPool::MemoryPool(size_t size, bool hugePages, uint32_t node) :
|
||||
m_size(size)
|
||||
{
|
||||
if (!size) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_memory = new VirtualMemory(size * pageSize, hugePages, false, node);
|
||||
}
|
||||
|
||||
|
||||
xmrig::MemoryPool::~MemoryPool()
|
||||
{
|
||||
delete m_memory;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::MemoryPool::isHugePages(uint32_t) const
|
||||
{
|
||||
return m_memory && m_memory->isHugePages();
|
||||
}
|
||||
|
||||
|
||||
uint8_t *xmrig::MemoryPool::get(size_t size, uint32_t)
|
||||
{
|
||||
assert(!(size % pageSize));
|
||||
|
||||
if (!m_memory || (m_memory->size() - m_offset) < size) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint8_t *out = m_memory->scratchpad() + m_offset;
|
||||
|
||||
m_offset += size;
|
||||
++m_refs;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::MemoryPool::release(uint32_t)
|
||||
{
|
||||
assert(m_refs > 0);
|
||||
|
||||
if (m_refs > 0) {
|
||||
--m_refs;
|
||||
}
|
||||
|
||||
if (m_refs == 0) {
|
||||
m_offset = 0;
|
||||
}
|
||||
}
|
66
src/crypto/common/MemoryPool.h
Normal file
66
src/crypto/common/MemoryPool.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_MEMORYPOOL_H
|
||||
#define XMRIG_MEMORYPOOL_H
|
||||
|
||||
|
||||
#include "backend/common/interfaces/IMemoryPool.h"
|
||||
#include "base/tools/Object.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class VirtualMemory;
|
||||
|
||||
|
||||
class MemoryPool : public IMemoryPool
|
||||
{
|
||||
public:
|
||||
XMRIG_DISABLE_COPY_MOVE_DEFAULT(MemoryPool)
|
||||
|
||||
MemoryPool(size_t size, bool hugePages, uint32_t node = 0);
|
||||
~MemoryPool() override;
|
||||
|
||||
protected:
|
||||
bool isHugePages(uint32_t node) const override;
|
||||
uint8_t *get(size_t size, uint32_t node) override;
|
||||
void release(uint32_t node) override;
|
||||
|
||||
private:
|
||||
size_t m_size = 0;
|
||||
size_t m_refs = 0;
|
||||
size_t m_offset = 0;
|
||||
VirtualMemory *m_memory = nullptr;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
|
||||
#endif /* XMRIG_MEMORYPOOL_H */
|
106
src/crypto/common/NUMAMemoryPool.cpp
Normal file
106
src/crypto/common/NUMAMemoryPool.cpp
Normal file
|
@ -0,0 +1,106 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "crypto/common/NUMAMemoryPool.h"
|
||||
#include "crypto/common/VirtualMemory.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "crypto/common/MemoryPool.h"
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
constexpr size_t pageSize = 2 * 1024 * 1024;
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::NUMAMemoryPool::NUMAMemoryPool(size_t size, bool hugePages) :
|
||||
m_hugePages(hugePages),
|
||||
m_nodeSize(std::max<size_t>(size / Cpu::info()->nodes(), 1)),
|
||||
m_size(size)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
xmrig::NUMAMemoryPool::~NUMAMemoryPool()
|
||||
{
|
||||
for (auto kv : m_map) {
|
||||
delete kv.second;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::NUMAMemoryPool::isHugePages(uint32_t node) const
|
||||
{
|
||||
if (!m_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return getOrCreate(node)->isHugePages(node);
|
||||
}
|
||||
|
||||
|
||||
uint8_t *xmrig::NUMAMemoryPool::get(size_t size, uint32_t node)
|
||||
{
|
||||
if (!m_size) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return getOrCreate(node)->get(size, node);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::NUMAMemoryPool::release(uint32_t node)
|
||||
{
|
||||
const auto pool = get(node);
|
||||
if (pool) {
|
||||
pool->release(node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
xmrig::IMemoryPool *xmrig::NUMAMemoryPool::get(uint32_t node) const
|
||||
{
|
||||
return m_map.count(node) ? m_map.at(node) : nullptr;
|
||||
}
|
||||
|
||||
|
||||
xmrig::IMemoryPool *xmrig::NUMAMemoryPool::getOrCreate(uint32_t node) const
|
||||
{
|
||||
auto pool = get(node);
|
||||
if (!pool) {
|
||||
pool = new MemoryPool(m_nodeSize, m_hugePages, node);
|
||||
m_map.insert({ node, pool });
|
||||
}
|
||||
|
||||
return pool;
|
||||
}
|
72
src/crypto/common/NUMAMemoryPool.h
Normal file
72
src/crypto/common/NUMAMemoryPool.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XMRIG_NUMAMEMORYPOOL_H
|
||||
#define XMRIG_NUMAMEMORYPOOL_H
|
||||
|
||||
|
||||
#include "backend/common/interfaces/IMemoryPool.h"
|
||||
#include "base/tools/Object.h"
|
||||
|
||||
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
class IMemoryPool;
|
||||
|
||||
|
||||
class NUMAMemoryPool : public IMemoryPool
|
||||
{
|
||||
public:
|
||||
XMRIG_DISABLE_COPY_MOVE_DEFAULT(NUMAMemoryPool)
|
||||
|
||||
NUMAMemoryPool(size_t size, bool hugePages);
|
||||
~NUMAMemoryPool() override;
|
||||
|
||||
protected:
|
||||
bool isHugePages(uint32_t node) const override;
|
||||
uint8_t *get(size_t size, uint32_t node) override;
|
||||
void release(uint32_t node) override;
|
||||
|
||||
private:
|
||||
IMemoryPool *get(uint32_t node) const;
|
||||
IMemoryPool *getOrCreate(uint32_t node) const;
|
||||
|
||||
bool m_hugePages = true;
|
||||
size_t m_nodeSize = 0;
|
||||
size_t m_size = 0;
|
||||
mutable std::map<uint32_t, IMemoryPool *> m_map;
|
||||
};
|
||||
|
||||
|
||||
} /* namespace xmrig */
|
||||
|
||||
|
||||
|
||||
#endif /* XMRIG_NUMAMEMORYPOOL_H */
|
|
@ -25,38 +25,102 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_HWLOC
|
||||
# include <hwloc.h>
|
||||
# include "backend/cpu/platform/HwlocCpuInfo.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include "crypto/common/VirtualMemory.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "crypto/common/MemoryPool.h"
|
||||
#include "crypto/common/portable/mm_malloc.h"
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_HWLOC
|
||||
# include "crypto/common/NUMAMemoryPool.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include <cinttypes>
|
||||
#include <mutex>
|
||||
|
||||
|
||||
uint32_t xmrig::VirtualMemory::bindToNUMANode(int64_t affinity)
|
||||
namespace xmrig {
|
||||
|
||||
static IMemoryPool *pool = nullptr;
|
||||
static std::mutex mutex;
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::VirtualMemory::VirtualMemory(size_t size, bool hugePages, bool usePool, uint32_t node, size_t alignSize) :
|
||||
m_size(align(size)),
|
||||
m_node(node)
|
||||
{
|
||||
# ifdef XMRIG_FEATURE_HWLOC
|
||||
if (affinity < 0 || Cpu::info()->nodes() < 2) {
|
||||
return 0;
|
||||
if (usePool) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
if (hugePages && !pool->isHugePages(node) && allocateLargePagesMemory()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto cpu = static_cast<HwlocCpuInfo *>(Cpu::info());
|
||||
hwloc_obj_t pu = hwloc_get_pu_obj_by_os_index(cpu->topology(), static_cast<unsigned>(affinity));
|
||||
m_scratchpad = pool->get(m_size, node);
|
||||
if (m_scratchpad) {
|
||||
m_flags.set(FLAG_HUGEPAGES, pool->isHugePages(node));
|
||||
m_flags.set(FLAG_EXTERNAL, true);
|
||||
|
||||
if (pu == nullptr || !cpu->membind(pu->nodeset)) {
|
||||
LOG_WARN("CPU #%02" PRId64 " warning: \"can't bind memory\"", affinity);
|
||||
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return hwloc_bitmap_first(pu->nodeset);
|
||||
# else
|
||||
return 0;
|
||||
# endif
|
||||
if (hugePages && allocateLargePagesMemory()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_scratchpad = static_cast<uint8_t*>(_mm_malloc(m_size, alignSize));
|
||||
}
|
||||
|
||||
|
||||
xmrig::VirtualMemory::~VirtualMemory()
|
||||
{
|
||||
if (!m_scratchpad) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_flags.test(FLAG_EXTERNAL)) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
pool->release(m_node);
|
||||
}
|
||||
else if (isHugePages()) {
|
||||
freeLargePagesMemory();
|
||||
}
|
||||
else {
|
||||
_mm_free(m_scratchpad);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef XMRIG_FEATURE_HWLOC
|
||||
uint32_t xmrig::VirtualMemory::bindToNUMANode(int64_t)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void xmrig::VirtualMemory::destroy()
|
||||
{
|
||||
delete pool;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::VirtualMemory::init(size_t poolSize, bool hugePages)
|
||||
{
|
||||
if (!pool) {
|
||||
osInit();
|
||||
}
|
||||
|
||||
# ifdef XMRIG_FEATURE_HWLOC
|
||||
if (Cpu::info()->nodes() > 1) {
|
||||
pool = new NUMAMemoryPool(align(poolSize, Cpu::info()->nodes()), hugePages);
|
||||
} else
|
||||
# endif
|
||||
{
|
||||
pool = new MemoryPool(poolSize, hugePages);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,8 +28,12 @@
|
|||
#define XMRIG_VIRTUALMEMORY_H
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "base/tools/Object.h"
|
||||
|
||||
|
||||
#include <bitset>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
|
||||
|
||||
|
@ -39,42 +43,49 @@ namespace xmrig {
|
|||
class VirtualMemory
|
||||
{
|
||||
public:
|
||||
inline VirtualMemory() {}
|
||||
VirtualMemory(size_t size, bool hugePages = true, size_t align = 64);
|
||||
XMRIG_DISABLE_COPY_MOVE_DEFAULT(VirtualMemory)
|
||||
|
||||
VirtualMemory(size_t size, bool hugePages, bool usePool, uint32_t node = 0, size_t alignSize = 64);
|
||||
~VirtualMemory();
|
||||
|
||||
inline bool isHugePages() const { return m_flags & HUGEPAGES; }
|
||||
inline bool isHugePages() const { return m_flags.test(FLAG_HUGEPAGES); }
|
||||
inline size_t size() const { return m_size; }
|
||||
inline uint8_t *scratchpad() const { return m_scratchpad; }
|
||||
|
||||
inline std::pair<size_t, size_t> hugePages() const
|
||||
{
|
||||
return std::pair<size_t, size_t>(isHugePages() ? (align(size()) / 2097152) : 0, align(size()) / 2097152);
|
||||
return { isHugePages() ? (align(size()) / 2097152) : 0, align(size()) / 2097152 };
|
||||
}
|
||||
|
||||
static bool isHugepagesAvailable();
|
||||
static uint32_t bindToNUMANode(int64_t affinity);
|
||||
static void *allocateExecutableMemory(size_t size);
|
||||
static void *allocateLargePagesMemory(size_t size);
|
||||
static void destroy();
|
||||
static void flushInstructionCache(void *p, size_t size);
|
||||
static void freeLargePagesMemory(void *p, size_t size);
|
||||
static void init(bool hugePages);
|
||||
static void init(size_t poolSize, bool hugePages);
|
||||
static void protectExecutableMemory(void *p, size_t size);
|
||||
static void unprotectExecutableMemory(void *p, size_t size);
|
||||
|
||||
static inline bool isHugepagesAvailable() { return (m_globalFlags & HUGEPAGES_AVAILABLE) != 0; }
|
||||
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
|
||||
FLAG_HUGEPAGES,
|
||||
FLAG_LOCK,
|
||||
FLAG_EXTERNAL,
|
||||
FLAG_MAX
|
||||
};
|
||||
|
||||
static int m_globalFlags;
|
||||
static void osInit();
|
||||
|
||||
int m_flags = 0;
|
||||
size_t m_size = 0;
|
||||
bool allocateLargePagesMemory();
|
||||
void freeLargePagesMemory();
|
||||
|
||||
const size_t m_size;
|
||||
const uint32_t m_node;
|
||||
std::bitset<FLAG_MAX> m_flags;
|
||||
uint8_t *m_scratchpad = nullptr;
|
||||
};
|
||||
|
||||
|
|
56
src/crypto/common/VirtualMemory_hwloc.cpp
Normal file
56
src/crypto/common/VirtualMemory_hwloc.cpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* XMRig
|
||||
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
|
||||
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
|
||||
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
|
||||
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
|
||||
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
|
||||
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "crypto/common/VirtualMemory.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "backend/cpu/platform/HwlocCpuInfo.h"
|
||||
#include "base/io/log/Log.h"
|
||||
|
||||
|
||||
#include <hwloc.h>
|
||||
|
||||
|
||||
uint32_t xmrig::VirtualMemory::bindToNUMANode(int64_t affinity)
|
||||
{
|
||||
if (affinity < 0 || Cpu::info()->nodes() < 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto cpu = static_cast<HwlocCpuInfo *>(Cpu::info());
|
||||
hwloc_obj_t pu = hwloc_get_pu_obj_by_os_index(cpu->topology(), static_cast<unsigned>(affinity));
|
||||
|
||||
char *buffer;
|
||||
hwloc_bitmap_asprintf(&buffer, pu->cpuset);
|
||||
|
||||
if (pu == nullptr || !cpu->membind(pu->nodeset)) {
|
||||
LOG_WARN("CPU #%02" PRId64 " warning: \"can't bind memory\"", affinity);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return hwloc_bitmap_first(pu->nodeset);
|
||||
}
|
|
@ -25,7 +25,7 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <cstdlib>
|
||||
#include <sys/mman.h>
|
||||
|
||||
|
||||
|
@ -38,51 +38,12 @@
|
|||
#endif
|
||||
|
||||
|
||||
int xmrig::VirtualMemory::m_globalFlags = 0;
|
||||
|
||||
|
||||
xmrig::VirtualMemory::VirtualMemory(size_t size, bool hugePages, size_t align) :
|
||||
m_size(VirtualMemory::align(size))
|
||||
bool xmrig::VirtualMemory::isHugepagesAvailable()
|
||||
{
|
||||
if (hugePages) {
|
||||
m_scratchpad = static_cast<uint8_t*>(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<uint8_t*>(_mm_malloc(m_size, align));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
# if defined(__APPLE__)
|
||||
|
@ -123,14 +84,6 @@ void xmrig::VirtualMemory::freeLargePagesMemory(void *p, size_t size)
|
|||
}
|
||||
|
||||
|
||||
void xmrig::VirtualMemory::init(bool hugePages)
|
||||
{
|
||||
if (hugePages) {
|
||||
m_globalFlags = HUGEPAGES | HUGEPAGES_AVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::VirtualMemory::protectExecutableMemory(void *p, size_t size)
|
||||
{
|
||||
mprotect(p, size, PROT_READ | PROT_EXEC);
|
||||
|
@ -141,3 +94,37 @@ void xmrig::VirtualMemory::unprotectExecutableMemory(void *p, size_t size)
|
|||
{
|
||||
mprotect(p, size, PROT_WRITE | PROT_EXEC);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::VirtualMemory::osInit()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::VirtualMemory::allocateLargePagesMemory()
|
||||
{
|
||||
m_scratchpad = static_cast<uint8_t*>(allocateLargePagesMemory(m_size));
|
||||
if (m_scratchpad) {
|
||||
m_flags.set(FLAG_HUGEPAGES, true);
|
||||
|
||||
madvise(m_scratchpad, m_size, MADV_RANDOM | MADV_WILLNEED);
|
||||
|
||||
if (mlock(m_scratchpad, m_size) == 0) {
|
||||
m_flags.set(FLAG_LOCK, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::VirtualMemory::freeLargePagesMemory()
|
||||
{
|
||||
if (m_flags.test(FLAG_LOCK)) {
|
||||
munlock(m_scratchpad, m_size);
|
||||
}
|
||||
|
||||
freeLargePagesMemory(m_scratchpad, m_size);
|
||||
}
|
||||
|
|
|
@ -36,6 +36,12 @@
|
|||
#include "crypto/common/VirtualMemory.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
static bool hugepagesAvailable = false;
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
SetLockPagesPrivilege: a function to obtain or
|
||||
release the privilege of locking physical pages.
|
||||
|
@ -83,7 +89,7 @@ static BOOL SetLockPagesPrivilege() {
|
|||
static LSA_UNICODE_STRING StringToLsaUnicodeString(LPCTSTR string) {
|
||||
LSA_UNICODE_STRING lsaString;
|
||||
|
||||
DWORD dwLen = (DWORD) wcslen(string);
|
||||
const auto dwLen = (DWORD) wcslen(string);
|
||||
lsaString.Buffer = (LPWSTR) string;
|
||||
lsaString.Length = (USHORT)((dwLen) * sizeof(WCHAR));
|
||||
lsaString.MaximumLength = (USHORT)((dwLen + 1) * sizeof(WCHAR));
|
||||
|
@ -141,37 +147,12 @@ static BOOL TrySetLockPagesPrivilege() {
|
|||
}
|
||||
|
||||
|
||||
int xmrig::VirtualMemory::m_globalFlags = 0;
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::VirtualMemory::VirtualMemory(size_t size, bool hugePages, size_t align) :
|
||||
m_size(VirtualMemory::align(size))
|
||||
bool xmrig::VirtualMemory::isHugepagesAvailable()
|
||||
{
|
||||
if (hugePages) {
|
||||
m_scratchpad = static_cast<uint8_t*>(allocateLargePagesMemory(m_size));
|
||||
if (m_scratchpad) {
|
||||
m_flags |= HUGEPAGES;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_scratchpad = static_cast<uint8_t*>(_mm_malloc(m_size, align));
|
||||
}
|
||||
|
||||
|
||||
xmrig::VirtualMemory::~VirtualMemory()
|
||||
{
|
||||
if (!m_scratchpad) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isHugePages()) {
|
||||
freeLargePagesMemory(m_scratchpad, m_size);
|
||||
}
|
||||
else {
|
||||
_mm_free(m_scratchpad);
|
||||
}
|
||||
return hugepagesAvailable;
|
||||
}
|
||||
|
||||
|
||||
|
@ -206,20 +187,6 @@ void xmrig::VirtualMemory::freeLargePagesMemory(void *p, size_t)
|
|||
}
|
||||
|
||||
|
||||
void xmrig::VirtualMemory::init(bool hugePages)
|
||||
{
|
||||
if (!hugePages) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_globalFlags = HUGEPAGES;
|
||||
|
||||
if (TrySetLockPagesPrivilege()) {
|
||||
m_globalFlags |= HUGEPAGES_AVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xmrig::VirtualMemory::protectExecutableMemory(void *p, size_t size)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
|
@ -232,3 +199,28 @@ void xmrig::VirtualMemory::unprotectExecutableMemory(void *p, size_t size)
|
|||
DWORD oldProtect;
|
||||
VirtualProtect(p, size, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::VirtualMemory::osInit()
|
||||
{
|
||||
hugepagesAvailable = TrySetLockPagesPrivilege();
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::VirtualMemory::allocateLargePagesMemory()
|
||||
{
|
||||
m_scratchpad = static_cast<uint8_t*>(allocateLargePagesMemory(m_size));
|
||||
if (m_scratchpad) {
|
||||
m_flags.set(FLAG_HUGEPAGES, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void xmrig::VirtualMemory::freeLargePagesMemory()
|
||||
{
|
||||
freeLargePagesMemory(m_scratchpad, m_size);
|
||||
}
|
||||
|
|
|
@ -43,11 +43,9 @@ xmrig::RxVm::RxVm(RxDataset *dataset, uint8_t *scratchpad, bool softAes)
|
|||
|
||||
if (!dataset->cache() || dataset->cache()->isJIT()) {
|
||||
m_flags |= RANDOMX_FLAG_JIT;
|
||||
m_vm = randomx_create_vm(static_cast<randomx_flags>(m_flags), nullptr, dataset->get(), scratchpad);
|
||||
}
|
||||
else {
|
||||
m_vm = randomx_create_vm(static_cast<randomx_flags>(m_flags), dataset->cache()->get(), dataset->get(), scratchpad);
|
||||
}
|
||||
|
||||
m_vm = randomx_create_vm(static_cast<randomx_flags>(m_flags), dataset->cache() ? dataset->cache()->get() : nullptr, dataset->get(), scratchpad);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ static inline void checkHash(const JobBundle &bundle, std::vector<JobResult> &re
|
|||
static void getResults(JobBundle &bundle, std::vector<JobResult> &results, uint32_t &errors, bool hwAES)
|
||||
{
|
||||
const auto &algorithm = bundle.job.algorithm();
|
||||
auto memory = new VirtualMemory(algorithm.l3(), false);
|
||||
auto memory = new VirtualMemory(algorithm.l3(), false, false);
|
||||
uint8_t hash[32]{ 0 };
|
||||
|
||||
if (algorithm.family() == Algorithm::RANDOM_X) {
|
||||
|
|
Loading…
Reference in a new issue