Merge branch 'dev'

This commit is contained in:
XMRig 2021-02-03 06:57:11 +07:00
commit 9396ecf93d
No known key found for this signature in database
GPG key ID: 446A53638BE94409
26 changed files with 342 additions and 200 deletions

View file

@ -1,3 +1,10 @@
# v6.8.1
- [#2064](https://github.com/xmrig/xmrig/pull/2064) Added documentation for config.json CPU options.
- [#2066](https://github.com/xmrig/xmrig/issues/2066) Fixed AMD GPUs health data readings on Linux.
- [#2067](https://github.com/xmrig/xmrig/pull/2067) Fixed compilation error when RandomX and Argon2 are disabled.
- [#2076](https://github.com/xmrig/xmrig/pull/2076) Added support for flexible huge page sizes on Linux.
- [#2077](https://github.com/xmrig/xmrig/pull/2077) Fixed `illegal instruction` crash on ARM.
# v6.8.0 # v6.8.0
- [#2052](https://github.com/xmrig/xmrig/pull/2052) Added DMI/SMBIOS reader. - [#2052](https://github.com/xmrig/xmrig/pull/2052) Added DMI/SMBIOS reader.
- Added information about memory modules on the miner startup and for online benchmark. - Added information about memory modules on the miner startup and for online benchmark.

View file

@ -75,6 +75,35 @@ Each number represent one thread and means CPU affinity, this is default format
``` ```
Internal format, but can be user defined. Internal format, but can be user defined.
## RandomX options
#### `init`
Thread count to initialize RandomX dataset. Auto-detect (`-1`) or any number greater than 0 to use that many threads.
#### `init-avx2`
Use AVX2 for dataset initialization. Faster on some CPUs. Auto-detect (`-1`), disabled (`0`), always enabled on CPUs that support AVX2 (`1`).
#### `mode`
RandomX mining mode: `auto`, `fast` (2 GB memory), `light` (256 MB memory).
#### `1gb-pages`
Use 1GB hugepages for RandomX dataset (Linux only). Enabled (`true`) or disabled (`false`). It gives 1-3% speedup.
#### `rdmsr`
Restore MSR register values to their original values on exit. Used together with `wrmsr`. Enabled (`true`) or disabled (`false`).
#### `wrmsr`
[MSR mod](https://xmrig.com/docs/miner/randomx-optimization-guide/msr). Enabled (`true`) or disabled (`false`). It gives up to 15% speedup depending on your system.
#### `cache_qos`
[Cache QoS](https://xmrig.com/docs/miner/randomx-optimization-guide/qos). Enabled (`true`) or disabled (`false`). It's useful when you can't or don't want to mine on all CPU cores to make mining hashrate more stable.
#### `numa`
NUMA support (better hashrate on multi-CPU servers and Ryzen Threadripper 1xxx/2xxx). Enabled (`true`) or disabled (`false`).
#### `scratchpad_prefetch_mode`
Which instruction to use in RandomX loop to prefetch data from scratchpad. `1` is default and fastest in most cases. Can be off (`0`), `prefetcht0` instruction (`1`), `prefetchnta` instruction (`2`, a bit faster on Coffee Lake and a few other CPUs), `mov` instruction (`3`).
## Shared options ## Shared options
#### `enabled` #### `enabled`
@ -83,23 +112,32 @@ Enable (`true`) or disable (`false`) CPU backend, by default `true`.
#### `huge-pages` #### `huge-pages`
Enable (`true`) or disable (`false`) huge pages support, by default `true`. Enable (`true`) or disable (`false`) huge pages support, by default `true`.
#### `huge-pages-jit`
Enable (`true`) or disable (`false`) huge pages support for RandomX JIT code, by default `false`. It gives a very small boost on Ryzen CPUs, but hashrate is unstable between launches. Use with caution.
#### `hw-aes` #### `hw-aes`
Force enable (`true`) or disable (`false`) hardware AES support. Default value `null` means miner autodetect this feature. Usually don't need change this option, this option useful for some rare cases when miner can't detect hardware AES, but it available. If you force enable this option, but your hardware not support it, miner will crash. Force enable (`true`) or disable (`false`) hardware AES support. Default value `null` means miner autodetect this feature. Usually don't need change this option, this option useful for some rare cases when miner can't detect hardware AES, but it available. If you force enable this option, but your hardware not support it, miner will crash.
#### `priority` #### `priority`
Mining threads priority, value from `1` (lowest priority) to `5` (highest possible priority). Default value `null` means miner don't change threads priority at all. Mining threads priority, value from `1` (lowest priority) to `5` (highest possible priority). Default value `null` means miner don't change threads priority at all. Setting priority higher than 2 can make your PC unresponsive.
#### `memory-pool` (since v4.3.0)
Use continuous, persistent memory block for mining threads, useful for preserve huge pages allocation while algorithm swithing. Possible values `false` (feature disabled, by default) or `true` or specific count of 2 MB huge pages. It helps to avoid loosing huge pages for scratchpads when RandomX dataset is updated and mining threads restart after a 2-3 days of mining.
#### `yield` (since v5.1.1)
Prefer system better system response/stability `true` (default value) or maximum hashrate `false`.
#### `asm` #### `asm`
Enable/configure or disable ASM optimizations. Possible values: `true`, `false`, `"intel"`, `"ryzen"`, `"bulldozer"`. Enable/configure or disable ASM optimizations. Possible values: `true`, `false`, `"intel"`, `"ryzen"`, `"bulldozer"`.
#### `argon2-impl` (since v3.1.0) #### `argon2-impl` (since v3.1.0)
Allow override automatically detected Argon2 implementation, this option added mostly for debug purposes, default value `null` means autodetect. Other possible values: `"x86_64"`, `"SSE2"`, `"SSSE3"`, `"XOP"`, `"AVX2"`, `"AVX-512F"`. Manual selection has no safe guards, if you CPU not support required instuctions, miner will crash. Allow override automatically detected Argon2 implementation, this option added mostly for debug purposes, default value `null` means autodetect. This is used in RandomX dataset initialization and also in some other mining algorithms. Other possible values: `"x86_64"`, `"SSE2"`, `"SSSE3"`, `"XOP"`, `"AVX2"`, `"AVX-512F"`. Manual selection has no safe guards - if your CPU doesn't support required instuctions, miner will crash.
#### `astrobwt-max-size`
AstroBWT algorithm: skip hashes with large stage 2 size, default: `550`, min: `400`, max: `1200`. Optimal value depends on your CPU/GPU
#### `astrobwt-avx2`
AstroBWT algorithm: use AVX2 code. It's faster on some CPUs and slower on other
#### `max-threads-hint` (since v4.2.0) #### `max-threads-hint` (since v4.2.0)
Maximum CPU threads count (in percentage) hint for autoconfig. [CPU_MAX_USAGE.md](CPU_MAX_USAGE.md) 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. Possible values `false` (feature disabled, by default) or `true` or specific count of 2 MB huge pages.
#### `yield` (since v5.1.1)
Prefer system better system response/stability `true` (default value) or maximum hashrate `false`.

View file

@ -146,7 +146,7 @@ static void print_memory(const Config *config)
return; return;
} }
const bool vm = Cpu::info()->isVM(); const bool printEmpty = reader.memory().size() <= 8;
for (const auto &memory : reader.memory()) { for (const auto &memory : reader.memory()) {
if (!memory.isValid()) { if (!memory.isValid()) {
@ -155,14 +155,14 @@ static void print_memory(const Config *config)
if (memory.size()) { if (memory.size()) {
Log::print(WHITE_BOLD(" %-13s") "%s: " CYAN_BOLD("%" PRIu64) CYAN(" GB ") WHITE_BOLD("%s @ %" PRIu64 " MHz ") BLACK_BOLD("%s"), Log::print(WHITE_BOLD(" %-13s") "%s: " CYAN_BOLD("%" PRIu64) CYAN(" GB ") WHITE_BOLD("%s @ %" PRIu64 " MHz ") BLACK_BOLD("%s"),
"", memory.slot().data(), memory.size() / oneGiB, memory.type(), memory.speed() / 1000000ULL, memory.product().data()); "", memory.id().data(), memory.size() / oneGiB, memory.type(), memory.speed() / 1000000ULL, memory.product().data());
} }
else if (!vm) { else if (printEmpty) {
Log::print(WHITE_BOLD(" %-13s") "%s: " BLACK_BOLD("<empty>"), "", memory.slot().data()); Log::print(WHITE_BOLD(" %-13s") "%s: " BLACK_BOLD("<empty>"), "", memory.slot().data());
} }
} }
const auto &board = vm ? reader.system() : reader.board(); const auto &board = Cpu::info()->isVM() ? reader.system() : reader.board();
if (board.isValid()) { if (board.isValid()) {
Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s") " - " WHITE_BOLD("%s"), "MOTHERBOARD", board.vendor().data(), board.product().data()); Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") WHITE_BOLD("%s") " - " WHITE_BOLD("%s"), "MOTHERBOARD", board.vendor().data(), board.product().data());

View file

@ -1,13 +1,6 @@
/* XMRig /* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com> * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org> * Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* 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 * 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 * it under the terms of the GNU General Public License as published by
@ -42,10 +35,15 @@ public:
PciTopology() = default; PciTopology() = default;
PciTopology(uint32_t bus, uint32_t device, uint32_t function) : m_valid(true), m_bus(bus), m_device(device), m_function(function) {} PciTopology(uint32_t bus, uint32_t device, uint32_t function) : m_valid(true), m_bus(bus), m_device(device), m_function(function) {}
inline bool isValid() const { return m_valid; } inline bool isEqual(const PciTopology &other) const { return m_valid == other.m_valid && toUint32() == other.toUint32(); }
inline uint8_t bus() const { return m_bus; } inline bool isValid() const { return m_valid; }
inline uint8_t device() const { return m_device; } inline uint8_t bus() const { return m_bus; }
inline uint8_t function() const { return m_function; } inline uint8_t device() const { return m_device; }
inline uint8_t function() const { return m_function; }
inline bool operator!=(const PciTopology &other) const { return !isEqual(other); }
inline bool operator<(const PciTopology &other) const { return toUint32() < other.toUint32(); }
inline bool operator==(const PciTopology &other) const { return isEqual(other); }
String toString() const String toString() const
{ {
@ -60,6 +58,8 @@ public:
} }
private: private:
inline uint32_t toUint32() const { return m_bus << 16 | m_device << 8 | m_function; }
bool m_valid = false; bool m_valid = false;
uint8_t m_bus = 0; uint8_t m_bus = 0;
uint8_t m_device = 0; uint8_t m_device = 0;

View file

@ -1,12 +1,6 @@
/* XMRig /* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com> * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org> * Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* 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-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -77,7 +71,7 @@ rapidjson::Value xmrig::CpuConfig::toJSON(rapidjson::Document &doc) const
Value obj(kObjectType); Value obj(kObjectType);
obj.AddMember(StringRef(kEnabled), m_enabled, allocator); obj.AddMember(StringRef(kEnabled), m_enabled, allocator);
obj.AddMember(StringRef(kHugePages), m_hugePages, allocator); obj.AddMember(StringRef(kHugePages), m_hugePageSize == 0 || m_hugePageSize == kDefaultHugePageSizeKb ? Value(isHugePages()) : Value(static_cast<uint32_t>(m_hugePageSize)), allocator);
obj.AddMember(StringRef(kHugePagesJit), m_hugePagesJit, allocator); obj.AddMember(StringRef(kHugePagesJit), m_hugePagesJit, allocator);
obj.AddMember(StringRef(kHwAes), m_aes == AES_AUTO ? Value(kNullType) : Value(m_aes == AES_HW), 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(kPriority), priority() != -1 ? Value(priority()) : Value(kNullType), allocator);
@ -137,14 +131,14 @@ void xmrig::CpuConfig::read(const rapidjson::Value &value)
{ {
if (value.IsObject()) { if (value.IsObject()) {
m_enabled = Json::getBool(value, kEnabled, m_enabled); m_enabled = Json::getBool(value, kEnabled, m_enabled);
m_hugePages = Json::getBool(value, kHugePages, m_hugePages);
m_hugePagesJit = Json::getBool(value, kHugePagesJit, m_hugePagesJit); m_hugePagesJit = Json::getBool(value, kHugePagesJit, m_hugePagesJit);
m_limit = Json::getUint(value, kMaxThreadsHint, m_limit); m_limit = Json::getUint(value, kMaxThreadsHint, m_limit);
m_yield = Json::getBool(value, kYield, m_yield); m_yield = Json::getBool(value, kYield, m_yield);
setAesMode(Json::getValue(value, kHwAes)); setAesMode(Json::getValue(value, kHwAes));
setPriority(Json::getInt(value, kPriority, -1)); setHugePages(Json::getValue(value, kHugePages));
setMemoryPool(Json::getValue(value, kMemoryPool)); setMemoryPool(Json::getValue(value, kMemoryPool));
setPriority(Json::getInt(value, kPriority, -1));
# ifdef XMRIG_FEATURE_ASM # ifdef XMRIG_FEATURE_ASM
m_assembly = Json::getValue(value, kAsm); m_assembly = Json::getValue(value, kAsm);
@ -218,6 +212,19 @@ void xmrig::CpuConfig::setAesMode(const rapidjson::Value &value)
} }
void xmrig::CpuConfig::setHugePages(const rapidjson::Value &value)
{
if (value.IsBool()) {
m_hugePageSize = value.GetBool() ? kDefaultHugePageSizeKb : 0U;
}
else if (value.IsUint()) {
const uint32_t size = value.GetUint();
m_hugePageSize = size < kOneGbPageSizeKb ? size : kDefaultHugePageSizeKb;
}
}
void xmrig::CpuConfig::setMemoryPool(const rapidjson::Value &value) void xmrig::CpuConfig::setMemoryPool(const rapidjson::Value &value)
{ {
if (value.IsBool()) { if (value.IsBool()) {

View file

@ -1,12 +1,6 @@
/* XMRig /* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com> * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org> * Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* 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-2020 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -75,8 +69,9 @@ public:
std::vector<CpuLaunchData> get(const Miner *miner, const Algorithm &algorithm) const; std::vector<CpuLaunchData> get(const Miner *miner, const Algorithm &algorithm) const;
void read(const rapidjson::Value &value); void read(const rapidjson::Value &value);
inline bool astrobwtAVX2() const { return m_astrobwtAVX2; }
inline bool isEnabled() const { return m_enabled; } inline bool isEnabled() const { return m_enabled; }
inline bool isHugePages() const { return m_hugePages; } inline bool isHugePages() const { return m_hugePageSize > 0; }
inline bool isHugePagesJit() const { return m_hugePagesJit; } inline bool isHugePagesJit() const { return m_hugePagesJit; }
inline bool isShouldSave() const { return m_shouldSave; } inline bool isShouldSave() const { return m_shouldSave; }
inline bool isYield() const { return m_yield; } inline bool isYield() const { return m_yield; }
@ -84,13 +79,17 @@ public:
inline const String &argon2Impl() const { return m_argon2Impl; } inline const String &argon2Impl() const { return m_argon2Impl; }
inline const Threads<CpuThreads> &threads() const { return m_threads; } inline const Threads<CpuThreads> &threads() const { return m_threads; }
inline int astrobwtMaxSize() const { return m_astrobwtMaxSize; } inline int astrobwtMaxSize() const { return m_astrobwtMaxSize; }
inline bool astrobwtAVX2() const { return m_astrobwtAVX2; }
inline int priority() const { return m_priority; } inline int priority() const { return m_priority; }
inline size_t hugePageSize() const { return m_hugePageSize * 1024U; }
inline uint32_t limit() const { return m_limit; } inline uint32_t limit() const { return m_limit; }
private: private:
constexpr static size_t kDefaultHugePageSizeKb = 2048U;
constexpr static size_t kOneGbPageSizeKb = 1048576U;
void generate(); void generate();
void setAesMode(const rapidjson::Value &value); void setAesMode(const rapidjson::Value &value);
void setHugePages(const rapidjson::Value &value);
void setMemoryPool(const rapidjson::Value &value); void setMemoryPool(const rapidjson::Value &value);
inline void setPriority(int priority) { m_priority = (priority >= -1 && priority <= 5) ? priority : -1; } inline void setPriority(int priority) { m_priority = (priority >= -1 && priority <= 5) ? priority : -1; }
@ -99,13 +98,13 @@ private:
Assembly m_assembly; Assembly m_assembly;
bool m_astrobwtAVX2 = false; bool m_astrobwtAVX2 = false;
bool m_enabled = true; bool m_enabled = true;
bool m_hugePages = true;
bool m_hugePagesJit = false; bool m_hugePagesJit = false;
bool m_shouldSave = false; bool m_shouldSave = false;
bool m_yield = true; bool m_yield = true;
int m_astrobwtMaxSize = 550; int m_astrobwtMaxSize = 550;
int m_memoryPool = 0; int m_memoryPool = 0;
int m_priority = -1; int m_priority = -1;
size_t m_hugePageSize = kDefaultHugePageSizeKb;
String m_argon2Impl; String m_argon2Impl;
Threads<CpuThreads> m_threads; Threads<CpuThreads> m_threads;
uint32_t m_limit = 100; uint32_t m_limit = 100;

View file

@ -1,7 +1,7 @@
/* XMRig /* XMRig
* Copyright (c) 2018 Riku Voipio <riku.voipio@iki.fi> * Copyright (c) 2018 Riku Voipio <riku.voipio@iki.fi>
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh> * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <support@xmrig.com> * Copyright (c) 2016-2021 XMRig <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -87,16 +87,22 @@ static const id_part arm_part[] = {
{ 0xd03, "Cortex-A53" }, { 0xd03, "Cortex-A53" },
{ 0xd04, "Cortex-A35" }, { 0xd04, "Cortex-A35" },
{ 0xd05, "Cortex-A55" }, { 0xd05, "Cortex-A55" },
{ 0xd06, "Cortex-A65" },
{ 0xd07, "Cortex-A57" }, { 0xd07, "Cortex-A57" },
{ 0xd08, "Cortex-A72" }, { 0xd08, "Cortex-A72" },
{ 0xd09, "Cortex-A73" }, { 0xd09, "Cortex-A73" },
{ 0xd0a, "Cortex-A75" }, { 0xd0a, "Cortex-A75" },
{ 0xd0b, "Cortex-A76" }, { 0xd0b, "Cortex-A76" },
{ 0xd0c, "Neoverse-N1" }, { 0xd0c, "Neoverse-N1" },
{ 0xd0d, "Cortex-A77" },
{ 0xd0e, "Cortex-A76AE" },
{ 0xd13, "Cortex-R52" }, { 0xd13, "Cortex-R52" },
{ 0xd20, "Cortex-M23" }, { 0xd20, "Cortex-M23" },
{ 0xd21, "Cortex-M33" }, { 0xd21, "Cortex-M33" },
{ 0xd41, "Cortex-A78" },
{ 0xd42, "Cortex-A78AE" },
{ 0xd4a, "Neoverse-E1" }, { 0xd4a, "Neoverse-E1" },
{ 0xd4b, "Cortex-A78C" },
{ -1, nullptr }, { -1, nullptr },
}; };
@ -150,6 +156,7 @@ static const id_part samsung_part[] = {
static const id_part nvidia_part[] = { static const id_part nvidia_part[] = {
{ 0x000, "Denver" }, { 0x000, "Denver" },
{ 0x003, "Denver 2" }, { 0x003, "Denver 2" },
{ 0x004, "Carmel" },
{ -1, nullptr }, { -1, nullptr },
}; };
@ -191,23 +198,36 @@ static const id_part intel_part[] = {
{ -1, nullptr }, { -1, nullptr },
}; };
static const struct id_part fujitsu_part[] = {
{ 0x001, "A64FX" },
{ -1, "unknown" },
};
static const id_part hisi_part[] = { static const id_part hisi_part[] = {
{ 0xd01, "Kunpeng-920" }, /* aka tsv110 */ { 0xd01, "Kunpeng-920" }, /* aka tsv110 */
{ -1, nullptr }, { -1, nullptr },
}; };
static const id_part apple_part[] = {
{ 0x022, "M1" },
{ 0x023, "M1" },
{ -1, nullptr },
};
static const hw_impl hw_implementer[] = { static const hw_impl hw_implementer[] = {
{ 0x41, arm_part, "ARM" }, { 0x41, arm_part, "ARM" },
{ 0x42, brcm_part, "Broadcom" }, { 0x42, brcm_part, "Broadcom" },
{ 0x43, cavium_part, "Cavium" }, { 0x43, cavium_part, "Cavium" },
{ 0x44, dec_part, "DEC" }, { 0x44, dec_part, "DEC" },
{ 0x46, fujitsu_part, "FUJITSU" },
{ 0x48, hisi_part, "HiSilicon" }, { 0x48, hisi_part, "HiSilicon" },
{ 0x4e, nvidia_part, "Nvidia" }, { 0x4e, nvidia_part, "Nvidia" },
{ 0x50, apm_part, "APM" }, { 0x50, apm_part, "APM" },
{ 0x51, qcom_part, "Qualcomm" }, { 0x51, qcom_part, "Qualcomm" },
{ 0x53, samsung_part, "Samsung" }, { 0x53, samsung_part, "Samsung" },
{ 0x56, marvell_part, "Marvell" }, { 0x56, marvell_part, "Marvell" },
{ 0x61, apple_part, "Apple" },
{ 0x66, faraday_part, "Faraday" }, { 0x66, faraday_part, "Faraday" },
{ 0x69, intel_part, "Intel" } { 0x69, intel_part, "Intel" }
}; };

View file

@ -1,8 +1,8 @@
/* XMRig /* XMRig
* Copyright 2008-2018 Advanced Micro Devices, Inc. * Copyright (c) 2008-2018 Advanced Micro Devices, Inc.
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh> * Copyright (c) 2020 Patrick Bollinger <https://github.com/pjbollinger>
* Copyright 2020 Patrick Bollinger <https://github.com/pjbollinger> * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -20,10 +20,13 @@
#include "backend/opencl/wrappers/AdlLib.h" #include "backend/opencl/wrappers/AdlLib.h"
#include "3rdparty/fmt/core.h"
#include "backend/opencl/wrappers/OclDevice.h" #include "backend/opencl/wrappers/OclDevice.h"
#include <dirent.h>
#include <fstream> #include <fstream>
#include <map>
#include <string> #include <string>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
@ -35,18 +38,27 @@ namespace xmrig {
bool AdlLib::m_initialized = false; bool AdlLib::m_initialized = false;
bool AdlLib::m_ready = false; bool AdlLib::m_ready = false;
static const std::string kPrefix = "/sys/bus/pci/drivers/amdgpu/"; static const std::string kPrefix = "/sys/bus/pci/drivers/amdgpu/";
static std::map<PciTopology, std::string> hwmon_cache;
static inline bool sysfs_is_file(const std::string &path) static inline bool sysfs_is_file(const char *path)
{ {
struct stat sb; struct stat sb;
return stat(path.c_str(), &sb) == 0 && ((sb.st_mode & S_IFMT) == S_IFREG); return stat(path, &sb) == 0 && ((sb.st_mode & S_IFMT) == S_IFREG);
} }
static inline bool sysfs_is_amdgpu(const std::string &path) static inline int dir_filter(const struct dirent *dirp)
{ {
return strlen(dirp->d_name) > 5 ? 1 : 0;
}
static bool sysfs_is_amdgpu(const char *path, char *buf, const char *filename)
{
strcpy(buf, filename);
if (!sysfs_is_file(path)) { if (!sysfs_is_file(path)) {
return false; return false;
} }
@ -63,8 +75,10 @@ static inline bool sysfs_is_amdgpu(const std::string &path)
} }
uint32_t sysfs_read(const std::string &path) static uint32_t sysfs_read(const char *path, char *buf, const char *filename)
{ {
strcpy(buf, filename);
std::ifstream file(path); std::ifstream file(path);
if (!file.is_open()) { if (!file.is_open()) {
return 0; return 0;
@ -77,18 +91,44 @@ uint32_t sysfs_read(const std::string &path)
} }
static inline std::string sysfs_prefix(const PciTopology &topology) static size_t sysfs_prefix(char path[PATH_MAX], const PciTopology &topology)
{ {
const std::string path = kPrefix + "0000:" + topology.toString().data() + "/hwmon/hwmon"; const auto it = hwmon_cache.find(topology);
if (it != hwmon_cache.end()) {
strcpy(path, it->second.data());
for (uint32_t i = 1; i < 10; ++i) { return it->second.size();
const std::string prefix = path + std::to_string(i) + "/";
if (sysfs_is_amdgpu(prefix + "name") && (sysfs_read(prefix + "temp1_input") || sysfs_read(prefix + "power1_average"))) {
return prefix;
}
} }
return {}; char *base = fmt::format_to(path, "{}0000:{}/hwmon/", kPrefix, topology.toString());
*base = '\0';
char *end = nullptr;
struct dirent **namelist;
int n = scandir(path, &namelist, dir_filter, nullptr);
if (n < 0) {
return {};
}
while (n--) {
if (!end) {
char *tmp = fmt::format_to(base, "{}/", namelist[n]->d_name);
end = (sysfs_is_amdgpu(path, tmp, "name") && (sysfs_read(path, tmp, "temp1_input") || sysfs_read(path, tmp, "power1_average"))) ? tmp : nullptr;
}
free(namelist[n]);
}
free(namelist);
if (end) {
*end = '\0';
hwmon_cache.insert({ topology, path });
return end - path;
}
return 0;
} }
@ -124,20 +164,22 @@ AdlHealth xmrig::AdlLib::health(const OclDevice &device)
return {}; return {};
} }
const auto prefix = sysfs_prefix(device.topology()); static char path[PATH_MAX]{};
if (prefix.empty()) {
char *buf = path + sysfs_prefix(path, device.topology());
if (buf == path) {
return {}; return {};
} }
AdlHealth health; AdlHealth health;
health.clock = sysfs_read(prefix + "freq1_input") / 1000000; health.clock = sysfs_read(path, buf, "freq1_input") / 1000000;
health.memClock = sysfs_read(prefix + "freq2_input") / 1000000; health.memClock = sysfs_read(path, buf, "freq2_input") / 1000000;
health.power = sysfs_read(prefix + "power1_average") / 1000000; health.power = sysfs_read(path, buf, "power1_average") / 1000000;
health.rpm = sysfs_read(prefix + "fan1_input"); health.rpm = sysfs_read(path, buf, "fan1_input");
health.temperature = sysfs_read(prefix + "temp2_input") / 1000; health.temperature = sysfs_read(path, buf, "temp2_input") / 1000;
if (!health.temperature) { if (!health.temperature) {
health.temperature = sysfs_read(prefix + "temp1_input") / 1000; health.temperature = sysfs_read(path, buf, "temp1_input") / 1000;
} }
return health; return health;

View file

@ -85,6 +85,7 @@ public:
BenchHashKey = 1047, BenchHashKey = 1047,
BenchTokenKey = 1048, BenchTokenKey = 1048,
DmiKey = 1049, DmiKey = 1049,
HugePageSizeKey = 1050,
// xmrig common // xmrig common
CPUPriorityKey = 1021, CPUPriorityKey = 1021,

View file

@ -50,7 +50,7 @@ int xmrig::Controller::init()
{ {
Base::init(); Base::init();
VirtualMemory::init(config()->cpu().memPoolSize(), config()->cpu().isHugePages()); VirtualMemory::init(config()->cpu().memPoolSize(), config()->cpu().hugePageSize());
m_network = std::make_shared<Network>(this); m_network = std::make_shared<Network>(this);

View file

@ -125,9 +125,10 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const
BaseTransform::transform(doc, key, arg); BaseTransform::transform(doc, key, arg);
switch (key) { switch (key) {
case IConfig::AVKey: /* --av */ case IConfig::AVKey: /* --av */
case IConfig::CPUPriorityKey: /* --cpu-priority */ case IConfig::CPUPriorityKey: /* --cpu-priority */
case IConfig::ThreadsKey: /* --threads */ case IConfig::ThreadsKey: /* --threads */
case IConfig::HugePageSizeKey: /* --hugepage-size */
return transformUint64(doc, key, static_cast<uint64_t>(strtol(arg, nullptr, 10))); return transformUint64(doc, key, static_cast<uint64_t>(strtol(arg, nullptr, 10)));
case IConfig::HugePagesKey: /* --no-huge-pages */ case IConfig::HugePagesKey: /* --no-huge-pages */
@ -149,8 +150,10 @@ void xmrig::ConfigTransform::transform(rapidjson::Document &doc, int key, const
case IConfig::YieldKey: /* --cpu-no-yield */ case IConfig::YieldKey: /* --cpu-no-yield */
return set(doc, CpuConfig::kField, CpuConfig::kYield, false); return set(doc, CpuConfig::kField, CpuConfig::kYield, false);
# ifdef XMRIG_ALGO_ARGON2
case IConfig::Argon2ImplKey: /* --argon2-impl */ case IConfig::Argon2ImplKey: /* --argon2-impl */
return set(doc, CpuConfig::kField, CpuConfig::kArgon2Impl, arg); return set(doc, CpuConfig::kField, CpuConfig::kArgon2Impl, arg);
# endif
# ifdef XMRIG_FEATURE_ASM # ifdef XMRIG_FEATURE_ASM
case IConfig::AssemblyKey: /* --asm */ case IConfig::AssemblyKey: /* --asm */
@ -304,6 +307,9 @@ void xmrig::ConfigTransform::transformUint64(rapidjson::Document &doc, int key,
case IConfig::CPUPriorityKey: /* --cpu-priority */ case IConfig::CPUPriorityKey: /* --cpu-priority */
return set(doc, CpuConfig::kField, CpuConfig::kPriority, arg); return set(doc, CpuConfig::kField, CpuConfig::kPriority, arg);
case IConfig::HugePageSizeKey: /* --hugepage-size */
return set(doc, CpuConfig::kField, CpuConfig::kHugePages, arg);
default: default:
break; break;
} }

View file

@ -71,6 +71,8 @@ static const option options[] = {
{ "nicehash", 0, nullptr, IConfig::NicehashKey }, { "nicehash", 0, nullptr, IConfig::NicehashKey },
{ "no-color", 0, nullptr, IConfig::ColorKey }, { "no-color", 0, nullptr, IConfig::ColorKey },
{ "no-huge-pages", 0, nullptr, IConfig::HugePagesKey }, { "no-huge-pages", 0, nullptr, IConfig::HugePagesKey },
{ "no-hugepages", 0, nullptr, IConfig::HugePagesKey },
{ "hugepage-size", 1, nullptr, IConfig::HugePageSizeKey },
{ "pass", 1, nullptr, IConfig::PasswordKey }, { "pass", 1, nullptr, IConfig::PasswordKey },
{ "print-time", 1, nullptr, IConfig::PrintTimeKey }, { "print-time", 1, nullptr, IConfig::PrintTimeKey },
{ "retries", 1, nullptr, IConfig::RetriesKey }, { "retries", 1, nullptr, IConfig::RetriesKey },

View file

@ -83,6 +83,9 @@ static inline const std::string &usage()
u += " --cpu-memory-pool=N number of 2 MB pages for persistent memory pool, -1 (auto), 0 (disable)\n"; u += " --cpu-memory-pool=N number of 2 MB pages for persistent memory pool, -1 (auto), 0 (disable)\n";
u += " --cpu-no-yield prefer maximum hashrate rather than system response/stability\n"; u += " --cpu-no-yield prefer maximum hashrate rather than system response/stability\n";
u += " --no-huge-pages disable huge pages support\n"; u += " --no-huge-pages disable huge pages support\n";
# ifdef XMRIG_OS_LINUX
u += " --hugepage-size=N custom hugepage size in kB\n";
# endif
u += " --asm=ASM ASM optimizations, possible values: auto, none, intel, ryzen, bulldozer\n"; u += " --asm=ASM ASM optimizations, possible values: auto, none, intel, ryzen, bulldozer\n";
# if defined(__x86_64__) || defined(_M_AMD64) # if defined(__x86_64__) || defined(_M_AMD64)
@ -155,7 +158,7 @@ static inline const std::string &usage()
u += " -l, --log-file=FILE log all output to a file\n"; u += " -l, --log-file=FILE log all output to a file\n";
u += " --print-time=N print hashrate report every N seconds\n"; u += " --print-time=N print hashrate report every N seconds\n";
# ifdef XMRIG_FEATURE_NVML # if defined(XMRIG_FEATURE_NVML) || defined(XMRIG_FEATURE_ADL)
u += " --health-print-time=N print health report every N seconds\n"; u += " --health-print-time=N print health report every N seconds\n";
# endif # endif
u += " --no-color disable colored output\n"; u += " --no-color disable colored output\n";

View file

@ -1,12 +1,6 @@
/* XMRig /* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com> * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org> * Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* 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-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 * 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 * it under the terms of the GNU General Public License as published by
@ -27,24 +21,16 @@
#include "crypto/common/VirtualMemory.h" #include "crypto/common/VirtualMemory.h"
namespace xmrig {
constexpr size_t twoMiB = 2U * 1024U * 1024U;
constexpr size_t oneGiB = 1024U * 1024U * 1024U;
} // namespace xmrig
xmrig::HugePagesInfo::HugePagesInfo(const VirtualMemory *memory) xmrig::HugePagesInfo::HugePagesInfo(const VirtualMemory *memory)
{ {
if (memory->isOneGbPages()) { if (memory->isOneGbPages()) {
size = VirtualMemory::align(memory->size(), oneGiB); size = VirtualMemory::align(memory->size(), VirtualMemory::kOneGiB);
total = size / oneGiB; total = size / VirtualMemory::kOneGiB;
allocated = size / oneGiB; allocated = size / VirtualMemory::kOneGiB;
} }
else { else {
size = memory->size(); size = VirtualMemory::alignToHugePageSize(memory->size());
total = size / twoMiB; total = size / VirtualMemory::hugePageSize();
allocated = memory->isHugePages() ? total : 0; allocated = memory->isHugePages() ? total : 0;
} }
} }

View file

@ -1,12 +1,6 @@
/* XMRig /* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com> * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org> * Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* 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-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 * 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 * it under the terms of the GNU General Public License as published by

View file

@ -1,6 +1,6 @@
/* XMRig /* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh> * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -18,8 +18,6 @@
#include "crypto/common/LinuxMemory.h" #include "crypto/common/LinuxMemory.h"
#include "3rdparty/fmt/core.h" #include "3rdparty/fmt/core.h"
#include "backend/cpu/Cpu.h"
#include "base/io/log/Log.h"
#include "crypto/common/VirtualMemory.h" #include "crypto/common/VirtualMemory.h"
@ -37,33 +35,32 @@ constexpr size_t twoMiB = 2U * 1024U * 1024U;
constexpr size_t oneGiB = 1024U * 1024U * 1024U; constexpr size_t oneGiB = 1024U * 1024U * 1024U;
static inline std::string sysfs_path(uint32_t node, bool oneGbPages, bool nr) static inline std::string sysfs_path(uint32_t node, size_t hugePageSize, bool nr)
{ {
return fmt::format("/sys/devices/system/node/node{}/hugepages/hugepages-{}kB/{}_hugepages", node, oneGbPages ? "1048576" : "2048", nr ? "nr" : "free"); return fmt::format("/sys/devices/system/node/node{}/hugepages/hugepages-{}kB/{}_hugepages", node, hugePageSize / 1024, nr ? "nr" : "free");
} }
static inline bool write_nr_hugepages(uint32_t node, bool oneGbPages, uint64_t count) { return LinuxMemory::write(sysfs_path(node, oneGbPages, true).c_str(), count); } static inline bool write_nr_hugepages(uint32_t node, size_t hugePageSize, uint64_t count) { return LinuxMemory::write(sysfs_path(node, hugePageSize, true).c_str(), count); }
static inline int64_t free_hugepages(uint32_t node, bool oneGbPages) { return LinuxMemory::read(sysfs_path(node, oneGbPages, false).c_str()); } static inline int64_t free_hugepages(uint32_t node, size_t hugePageSize) { return LinuxMemory::read(sysfs_path(node, hugePageSize, false).c_str()); }
static inline int64_t nr_hugepages(uint32_t node, bool oneGbPages) { return LinuxMemory::read(sysfs_path(node, oneGbPages, true).c_str()); } static inline int64_t nr_hugepages(uint32_t node, size_t hugePageSize) { return LinuxMemory::read(sysfs_path(node, hugePageSize, true).c_str()); }
} // namespace xmrig } // namespace xmrig
bool xmrig::LinuxMemory::reserve(size_t size, uint32_t node, bool oneGbPages) bool xmrig::LinuxMemory::reserve(size_t size, uint32_t node, size_t hugePageSize)
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);
const size_t pageSize = oneGbPages ? oneGiB : twoMiB; const size_t required = VirtualMemory::align(size, hugePageSize) / hugePageSize;
const size_t required = VirtualMemory::align(size, pageSize) / pageSize;
const auto available = free_hugepages(node, oneGbPages); const auto available = free_hugepages(node, hugePageSize);
if (available < 0 || static_cast<size_t>(available) >= required) { if (available < 0 || static_cast<size_t>(available) >= required) {
return false; return false;
} }
return write_nr_hugepages(node, oneGbPages, std::max<size_t>(nr_hugepages(node, oneGbPages), 0) + (required - available)); return write_nr_hugepages(node, hugePageSize, std::max<size_t>(nr_hugepages(node, hugePageSize), 0) + (required - available));
} }

View file

@ -1,6 +1,6 @@
/* XMRig /* XMRig
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh> * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -30,7 +30,7 @@ namespace xmrig {
class LinuxMemory class LinuxMemory
{ {
public: public:
static bool reserve(size_t size, uint32_t node, bool oneGbPages = false); static bool reserve(size_t size, uint32_t node, size_t hugePageSize);
static bool write(const char *path, uint64_t value); static bool write(const char *path, uint64_t value);
static int64_t read(const char *path); static int64_t read(const char *path);

View file

@ -1,7 +1,7 @@
/* XMRig /* XMRig
* Copyright (c) 2018-2020 tevador <tevador@gmail.com> * Copyright (c) 2018-2020 tevador <tevador@gmail.com>
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh> * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -36,16 +36,19 @@
namespace xmrig { namespace xmrig {
static IMemoryPool *pool = nullptr;
size_t VirtualMemory::m_hugePageSize = VirtualMemory::kDefaultHugePageSize;
static IMemoryPool *pool = nullptr;
static std::mutex mutex; static std::mutex mutex;
} // namespace xmrig } // namespace xmrig
xmrig::VirtualMemory::VirtualMemory(size_t size, bool hugePages, bool oneGbPages, bool usePool, uint32_t node, size_t alignSize) : xmrig::VirtualMemory::VirtualMemory(size_t size, bool hugePages, bool oneGbPages, bool usePool, uint32_t node, size_t alignSize) :
m_size(align(size)), m_size(alignToHugePageSize(size)),
m_capacity(m_size), m_node(node),
m_node(node) m_capacity(m_size)
{ {
if (usePool) { if (usePool) {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);
@ -114,18 +117,18 @@ void xmrig::VirtualMemory::destroy()
} }
void xmrig::VirtualMemory::init(size_t poolSize, bool hugePages) void xmrig::VirtualMemory::init(size_t poolSize, size_t hugePageSize)
{ {
if (!pool) { if (!pool) {
osInit(hugePages); osInit(hugePageSize);
} }
# ifdef XMRIG_FEATURE_HWLOC # ifdef XMRIG_FEATURE_HWLOC
if (Cpu::info()->nodes() > 1) { if (Cpu::info()->nodes() > 1) {
pool = new NUMAMemoryPool(align(poolSize, Cpu::info()->nodes()), hugePages); pool = new NUMAMemoryPool(align(poolSize, Cpu::info()->nodes()), hugePageSize > 0);
} else } else
# endif # endif
{ {
pool = new MemoryPool(poolSize, hugePages); pool = new MemoryPool(poolSize, hugePageSize > 0);
} }
} }

View file

@ -1,7 +1,7 @@
/* XMRig /* XMRig
* Copyright (c) 2018-2020 tevador <tevador@gmail.com> * Copyright (c) 2018-2020 tevador <tevador@gmail.com>
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh> * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -39,6 +39,9 @@ class VirtualMemory
public: public:
XMRIG_DISABLE_COPY_MOVE_DEFAULT(VirtualMemory) XMRIG_DISABLE_COPY_MOVE_DEFAULT(VirtualMemory)
constexpr static size_t kDefaultHugePageSize = 2U * 1024U * 1024U;
constexpr static size_t kOneGiB = 1024U * 1024U * 1024U;
VirtualMemory(size_t size, bool hugePages, bool oneGbPages, bool usePool, uint32_t node = 0, size_t alignSize = 64); VirtualMemory(size_t size, bool hugePages, bool oneGbPages, bool usePool, uint32_t node = 0, size_t alignSize = 64);
~VirtualMemory(); ~VirtualMemory();
@ -65,9 +68,11 @@ public:
static void destroy(); static void destroy();
static void flushInstructionCache(void *p, size_t size); static void flushInstructionCache(void *p, size_t size);
static void freeLargePagesMemory(void *p, size_t size); static void freeLargePagesMemory(void *p, size_t size);
static void init(size_t poolSize, bool hugePages); static void init(size_t poolSize, size_t hugePageSize);
static inline constexpr size_t align(size_t pos, size_t align = 2097152) { return ((pos - 1) / align + 1) * align; } static inline constexpr size_t align(size_t pos, size_t align = kDefaultHugePageSize) { return ((pos - 1) / align + 1) * align; }
static inline size_t alignToHugePageSize(size_t pos) { return align(pos, hugePageSize()); }
static inline size_t hugePageSize() { return m_hugePageSize; }
private: private:
enum Flags { enum Flags {
@ -78,15 +83,17 @@ private:
FLAG_MAX FLAG_MAX
}; };
static void osInit(bool hugePages); static void osInit(size_t hugePageSize);
bool allocateLargePagesMemory(); bool allocateLargePagesMemory();
bool allocateOneGbPagesMemory(); bool allocateOneGbPagesMemory();
void freeLargePagesMemory(); void freeLargePagesMemory();
static size_t m_hugePageSize;
const size_t m_size; const size_t m_size;
size_t m_capacity;
const uint32_t m_node; const uint32_t m_node;
size_t m_capacity;
std::bitset<FLAG_MAX> m_flags; std::bitset<FLAG_MAX> m_flags;
uint8_t *m_scratchpad = nullptr; uint8_t *m_scratchpad = nullptr;
}; };

View file

@ -1,7 +1,7 @@
/* XMRig /* XMRig
* Copyright (c) 2018-2020 tevador <tevador@gmail.com> * Copyright (c) 2018-2020 tevador <tevador@gmail.com>
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh> * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -18,13 +18,14 @@
*/ */
#include <cstdlib> #include "crypto/common/VirtualMemory.h"
#include <sys/mman.h>
#include "backend/cpu/Cpu.h" #include "backend/cpu/Cpu.h"
#include "crypto/common/portable/mm_malloc.h" #include "crypto/common/portable/mm_malloc.h"
#include "crypto/common/VirtualMemory.h"
#include <cmath>
#include <cstdlib>
#include <sys/mman.h>
#ifdef XMRIG_OS_APPLE #ifdef XMRIG_OS_APPLE
@ -42,14 +43,21 @@
#endif #endif
#if defined(XMRIG_OS_LINUX) #ifdef XMRIG_OS_LINUX
# if (defined(MAP_HUGE_1GB) || defined(MAP_HUGE_SHIFT))
# define XMRIG_HAS_1GB_PAGES
# endif
# include "crypto/common/LinuxMemory.h" # include "crypto/common/LinuxMemory.h"
#endif #endif
#ifndef MAP_HUGE_SHIFT
# define MAP_HUGE_SHIFT 26
#endif
#ifndef MAP_HUGE_MASK
# define MAP_HUGE_MASK 0x3f
#endif
#ifdef XMRIG_SECURE_JIT #ifdef XMRIG_SECURE_JIT
# define SECURE_PROT_EXEC 0 # define SECURE_PROT_EXEC 0
#else #else
@ -57,6 +65,19 @@
#endif #endif
namespace xmrig {
#ifdef XMRIG_OS_LINUX
static inline int hugePagesFlag(size_t size)
{
return (static_cast<int>(log2(size)) & MAP_HUGE_MASK) << MAP_HUGE_SHIFT;
}
#endif
} // namespace xmrig
bool xmrig::VirtualMemory::isHugepagesAvailable() bool xmrig::VirtualMemory::isHugepagesAvailable()
{ {
# if defined(XMRIG_OS_MACOS) && defined(XMRIG_ARM) # if defined(XMRIG_OS_MACOS) && defined(XMRIG_ARM)
@ -69,7 +90,7 @@ bool xmrig::VirtualMemory::isHugepagesAvailable()
bool xmrig::VirtualMemory::isOneGbPagesAvailable() bool xmrig::VirtualMemory::isOneGbPagesAvailable()
{ {
# ifdef XMRIG_HAS_1GB_PAGES # ifdef XMRIG_OS_LINUX
return Cpu::info()->hasOneGbPages(); return Cpu::info()->hasOneGbPages();
# else # else
return false; return false;
@ -126,18 +147,10 @@ void *xmrig::VirtualMemory::allocateExecutableMemory(size_t size, bool hugePages
# else # else
# if defined(MAP_HUGE_2MB)
constexpr int flag_2mb = MAP_HUGE_2MB;
# elif defined(MAP_HUGE_SHIFT)
constexpr int flag_2mb = (21 << MAP_HUGE_SHIFT);
# else
constexpr int flag_2mb = 0;
# endif
void *mem = nullptr; void *mem = nullptr;
if (hugePages) { if (hugePages) {
mem = mmap(0, align(size), PROT_READ | PROT_WRITE | SECURE_PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE | flag_2mb, -1, 0); mem = mmap(0, align(size), PROT_READ | PROT_WRITE | SECURE_PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE | hugePagesFlag(hugePageSize()), -1, 0);
} }
if (!mem) { if (!mem) {
@ -157,17 +170,7 @@ void *xmrig::VirtualMemory::allocateLargePagesMemory(size_t size)
# elif defined(__FreeBSD__) # elif defined(__FreeBSD__)
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0); void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0);
# else # else
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE | hugePagesFlag(hugePageSize()), 0, 0);
# if defined(MAP_HUGE_2MB)
constexpr int flag_2mb = MAP_HUGE_2MB;
# elif defined(MAP_HUGE_SHIFT)
constexpr int flag_2mb = (21 << MAP_HUGE_SHIFT);
# else
constexpr int flag_2mb = 0;
# endif
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE | flag_2mb, 0, 0);
# endif # endif
return mem == MAP_FAILED ? nullptr : mem; return mem == MAP_FAILED ? nullptr : mem;
@ -176,17 +179,9 @@ void *xmrig::VirtualMemory::allocateLargePagesMemory(size_t size)
void *xmrig::VirtualMemory::allocateOneGbPagesMemory(size_t size) void *xmrig::VirtualMemory::allocateOneGbPagesMemory(size_t size)
{ {
# ifdef XMRIG_HAS_1GB_PAGES # ifdef XMRIG_OS_LINUX
if (isOneGbPagesAvailable()) { if (isOneGbPagesAvailable()) {
# if defined(MAP_HUGE_1GB) void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE | hugePagesFlag(kOneGiB), 0, 0);
constexpr int flag_1gb = MAP_HUGE_1GB;
# elif defined(MAP_HUGE_SHIFT)
constexpr int flag_1gb = (30 << MAP_HUGE_SHIFT);
# else
constexpr int flag_1gb = 0;
# endif
void *mem = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE | flag_1gb, 0, 0);
return mem == MAP_FAILED ? nullptr : mem; return mem == MAP_FAILED ? nullptr : mem;
} }
@ -212,15 +207,18 @@ void xmrig::VirtualMemory::freeLargePagesMemory(void *p, size_t size)
} }
void xmrig::VirtualMemory::osInit(bool) void xmrig::VirtualMemory::osInit(size_t hugePageSize)
{ {
if (hugePageSize) {
m_hugePageSize = hugePageSize;
}
} }
bool xmrig::VirtualMemory::allocateLargePagesMemory() bool xmrig::VirtualMemory::allocateLargePagesMemory()
{ {
# if defined(XMRIG_OS_LINUX) # ifdef XMRIG_OS_LINUX
LinuxMemory::reserve(m_size, m_node); LinuxMemory::reserve(m_size, m_node, hugePageSize());
# endif # endif
m_scratchpad = static_cast<uint8_t*>(allocateLargePagesMemory(m_size)); m_scratchpad = static_cast<uint8_t*>(allocateLargePagesMemory(m_size));
@ -242,8 +240,8 @@ bool xmrig::VirtualMemory::allocateLargePagesMemory()
bool xmrig::VirtualMemory::allocateOneGbPagesMemory() bool xmrig::VirtualMemory::allocateOneGbPagesMemory()
{ {
# if defined(XMRIG_HAS_1GB_PAGES) # ifdef XMRIG_OS_LINUX
LinuxMemory::reserve(m_size, m_node, true); LinuxMemory::reserve(m_size, m_node, kOneGiB);
# endif # endif
m_scratchpad = static_cast<uint8_t*>(allocateOneGbPagesMemory(m_size)); m_scratchpad = static_cast<uint8_t*>(allocateOneGbPagesMemory(m_size));

View file

@ -1,7 +1,7 @@
/* XMRig /* XMRig
* Copyright (c) 2018-2020 tevador <tevador@gmail.com> * Copyright (c) 2018-2020 tevador <tevador@gmail.com>
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh> * Copyright (c) 2018-2021 SChernykh <https://github.com/SChernykh>
* Copyright (c) 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com> * Copyright (c) 2016-2021 XMRig <https://github.com/xmrig>, <support@xmrig.com>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -24,9 +24,9 @@
#include <tchar.h> #include <tchar.h>
#include "crypto/common/VirtualMemory.h"
#include "base/io/log/Log.h" #include "base/io/log/Log.h"
#include "crypto/common/portable/mm_malloc.h" #include "crypto/common/portable/mm_malloc.h"
#include "crypto/common/VirtualMemory.h"
#ifdef XMRIG_SECURE_JIT #ifdef XMRIG_SECURE_JIT
@ -233,9 +233,9 @@ void xmrig::VirtualMemory::freeLargePagesMemory(void *p, size_t)
} }
void xmrig::VirtualMemory::osInit(bool hugePages) void xmrig::VirtualMemory::osInit(size_t hugePageSize)
{ {
if (hugePages) { if (hugePageSize) {
hugepagesAvailable = TrySetLockPagesPrivilege(); hugepagesAvailable = TrySetLockPagesPrivilege();
} }
} }

View file

@ -171,7 +171,7 @@ void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& con
emit32(ARMV8A::EOR | 10 | (IntRegMap[config.readReg0] << 5) | (IntRegMap[config.readReg1] << 16), code, codePos); emit32(ARMV8A::EOR | 10 | (IntRegMap[config.readReg0] << 5) | (IntRegMap[config.readReg1] << 16), code, codePos);
# ifndef XMRIG_OS_APPLE # ifndef XMRIG_OS_APPLE
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), reinterpret_cast<char*>(code + codePos)); xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), codePos - MainLoopBegin);
# endif # endif
} }
@ -237,7 +237,7 @@ void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration
emit32(ARMV8A::ADD_IMM_HI | 2 | (2 << 5) | (imm_hi << 10), code, codePos); emit32(ARMV8A::ADD_IMM_HI | 2 | (2 << 5) | (imm_hi << 10), code, codePos);
# ifndef XMRIG_OS_APPLE # ifndef XMRIG_OS_APPLE
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), reinterpret_cast<char*>(code + codePos)); xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), codePos - MainLoopBegin);
# endif # endif
} }
@ -364,7 +364,7 @@ void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[N])
codePos += p2 - p1; codePos += p2 - p1;
# ifndef XMRIG_OS_APPLE # ifndef XMRIG_OS_APPLE
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + CodeSize), reinterpret_cast<char*>(code + codePos)); xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + CodeSize), codePos - MainLoopBegin);
# endif # endif
} }
@ -401,6 +401,10 @@ void JitCompilerA64::allocate(size_t size)
code = static_cast<uint8_t*>(allocExecutableMemory(allocatedSize, hugePages)); code = static_cast<uint8_t*>(allocExecutableMemory(allocatedSize, hugePages));
memcpy(code, reinterpret_cast<const void *>(randomx_program_aarch64), CodeSize); memcpy(code, reinterpret_cast<const void *>(randomx_program_aarch64), CodeSize);
# ifndef XMRIG_OS_APPLE
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code), CodeSize);
# endif
} }

View file

@ -113,7 +113,6 @@ private:
Mode readMode(const rapidjson::Value &value) const; Mode readMode(const rapidjson::Value &value) const;
bool m_numa = true;
bool m_oneGbPages = false; bool m_oneGbPages = false;
bool m_rdmsr = true; bool m_rdmsr = true;
int m_threads = -1; int m_threads = -1;
@ -123,6 +122,7 @@ private:
ScratchpadPrefetchMode m_scratchpadPrefetchMode = ScratchpadPrefetchT0; ScratchpadPrefetchMode m_scratchpadPrefetchMode = ScratchpadPrefetchT0;
# ifdef XMRIG_FEATURE_HWLOC # ifdef XMRIG_FEATURE_HWLOC
bool m_numa = true;
std::vector<uint32_t> m_nodeset; std::vector<uint32_t> m_nodeset;
# endif # endif

View file

@ -20,17 +20,22 @@
#include "hw/dmi/DmiMemory.h" #include "hw/dmi/DmiMemory.h"
#include "3rdparty/fmt/format.h"
#include "3rdparty/rapidjson/document.h" #include "3rdparty/rapidjson/document.h"
#include "hw/dmi/DmiTools.h" #include "hw/dmi/DmiTools.h"
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <regex>
namespace xmrig { namespace xmrig {
static const char *kIdFormat = "DIMM_{}{}";
static inline uint16_t dmi_memory_device_width(uint16_t code) static inline uint16_t dmi_memory_device_width(uint16_t code)
{ {
return (code == 0xFFFF || code == 0) ? 0 : code; return (code == 0xFFFF || code == 0) ? 0 : code;
@ -143,9 +148,9 @@ xmrig::DmiMemory::DmiMemory(dmi_header *h)
m_size = (1024ULL * (size & 0x7FFF) * ((size & 0x8000) ? 1 : 1024ULL)); m_size = (1024ULL * (size & 0x7FFF) * ((size & 0x8000) ? 1 : 1024ULL));
} }
setId(dmi_string(h, 0x10), dmi_string(h, 0x11));
m_formFactor = h->data[0x0E]; m_formFactor = h->data[0x0E];
m_slot = dmi_string(h, 0x10);
m_bank = dmi_string(h, 0x11);
m_type = h->data[0x12]; m_type = h->data[0x12];
if (!m_size || h->length < 0x17) { if (!m_size || h->length < 0x17) {
@ -201,6 +206,7 @@ rapidjson::Value xmrig::DmiMemory::toJSON(rapidjson::Document &doc) const
auto &allocator = doc.GetAllocator(); auto &allocator = doc.GetAllocator();
Value out(kObjectType); Value out(kObjectType);
out.AddMember("id", id().toJSON(doc), allocator);
out.AddMember("slot", m_slot.toJSON(doc), allocator); out.AddMember("slot", m_slot.toJSON(doc), allocator);
out.AddMember("type", StringRef(type()), allocator); out.AddMember("type", StringRef(type()), allocator);
out.AddMember("form_factor", StringRef(formFactor()), allocator); out.AddMember("form_factor", StringRef(formFactor()), allocator);
@ -217,3 +223,21 @@ rapidjson::Value xmrig::DmiMemory::toJSON(rapidjson::Document &doc) const
return out; return out;
} }
#endif #endif
void xmrig::DmiMemory::setId(const char *slot, const char *bank)
{
m_slot = slot;
m_bank = bank;
std::cmatch cm;
if (std::regex_match(slot, cm, std::regex("^Channel([A-Z])[-_]DIMM(\\d+)$", std::regex_constants::icase))) {
m_id = fmt::format(kIdFormat, cm.str(1), cm.str(2)).c_str();
}
else if (std::regex_search(bank, cm, std::regex("CHANNEL ([A-Z])$"))) {
std::cmatch cm2;
if (std::regex_match(slot, cm2, std::regex("^DIMM (\\d+)$"))) {
m_id = fmt::format(kIdFormat, cm.str(1), cm2.str(1)).c_str();
}
}
}

View file

@ -39,6 +39,7 @@ public:
inline bool isValid() const { return !m_slot.isEmpty(); } inline bool isValid() const { return !m_slot.isEmpty(); }
inline const String &bank() const { return m_bank; } inline const String &bank() const { return m_bank; }
inline const String &id() const { return m_id.isNull() ? m_slot : m_id; }
inline const String &product() const { return m_product; } inline const String &product() const { return m_product; }
inline const String &slot() const { return m_slot; } inline const String &slot() const { return m_slot; }
inline const String &vendor() const { return m_vendor; } inline const String &vendor() const { return m_vendor; }
@ -57,7 +58,10 @@ public:
# endif # endif
private: private:
void setId(const char *slot, const char *bank);
String m_bank; String m_bank;
String m_id;
String m_product; String m_product;
String m_slot; String m_slot;
String m_vendor; String m_vendor;

View file

@ -28,7 +28,7 @@
#define APP_ID "xmrig" #define APP_ID "xmrig"
#define APP_NAME "XMRig" #define APP_NAME "XMRig"
#define APP_DESC "XMRig miner" #define APP_DESC "XMRig miner"
#define APP_VERSION "6.8.0" #define APP_VERSION "6.8.1-dev"
#define APP_DOMAIN "xmrig.com" #define APP_DOMAIN "xmrig.com"
#define APP_SITE "www.xmrig.com" #define APP_SITE "www.xmrig.com"
#define APP_COPYRIGHT "Copyright (C) 2016-2021 xmrig.com" #define APP_COPYRIGHT "Copyright (C) 2016-2021 xmrig.com"
@ -36,7 +36,7 @@
#define APP_VER_MAJOR 6 #define APP_VER_MAJOR 6
#define APP_VER_MINOR 8 #define APP_VER_MINOR 8
#define APP_VER_PATCH 0 #define APP_VER_PATCH 1
#ifdef _MSC_VER #ifdef _MSC_VER
# if (_MSC_VER >= 1920) # if (_MSC_VER >= 1920)