This commit is contained in:
commit
01e2945ab7
125 changed files with 4772 additions and 2073 deletions
|
@ -68,17 +68,15 @@ static std::mutex mutex;
|
|||
struct CpuLaunchStatus
|
||||
{
|
||||
public:
|
||||
inline size_t hugePages() const { return m_hugePages; }
|
||||
inline size_t memory() const { return m_ways * m_memory; }
|
||||
inline size_t pages() const { return m_pages; }
|
||||
inline size_t threads() const { return m_threads; }
|
||||
inline size_t ways() const { return m_ways; }
|
||||
inline const HugePagesInfo &hugePages() const { return m_hugePages; }
|
||||
inline size_t memory() const { return m_ways * m_memory; }
|
||||
inline size_t threads() const { return m_threads; }
|
||||
inline size_t ways() const { return m_ways; }
|
||||
|
||||
inline void start(const std::vector<CpuLaunchData> &threads, size_t memory)
|
||||
{
|
||||
m_hugePages = 0;
|
||||
m_hugePages.reset();
|
||||
m_memory = memory;
|
||||
m_pages = 0;
|
||||
m_started = 0;
|
||||
m_errors = 0;
|
||||
m_threads = threads.size();
|
||||
|
@ -89,11 +87,9 @@ public:
|
|||
inline bool started(IWorker *worker, bool ready)
|
||||
{
|
||||
if (ready) {
|
||||
auto hugePages = worker->memory()->hugePages();
|
||||
|
||||
m_started++;
|
||||
m_hugePages += hugePages.first;
|
||||
m_pages += hugePages.second;
|
||||
|
||||
m_hugePages += worker->memory()->hugePages();
|
||||
m_ways += worker->intensity();
|
||||
}
|
||||
else {
|
||||
|
@ -115,19 +111,18 @@ public:
|
|||
tag,
|
||||
m_errors == 0 ? CYAN_BOLD_S : YELLOW_BOLD_S,
|
||||
m_started, m_threads, m_ways,
|
||||
(m_hugePages == m_pages ? GREEN_BOLD_S : (m_hugePages == 0 ? RED_BOLD_S : YELLOW_BOLD_S)),
|
||||
m_hugePages == 0 ? 0.0 : static_cast<double>(m_hugePages) / m_pages * 100.0,
|
||||
m_hugePages, m_pages,
|
||||
(m_hugePages.isFullyAllocated() ? GREEN_BOLD_S : (m_hugePages.allocated == 0 ? RED_BOLD_S : YELLOW_BOLD_S)),
|
||||
m_hugePages.percent(),
|
||||
m_hugePages.allocated, m_hugePages.total,
|
||||
memory() / 1024,
|
||||
Chrono::steadyMSecs() - m_ts
|
||||
);
|
||||
}
|
||||
|
||||
private:
|
||||
HugePagesInfo m_hugePages;
|
||||
size_t m_errors = 0;
|
||||
size_t m_hugePages = 0;
|
||||
size_t m_memory = 0;
|
||||
size_t m_pages = 0;
|
||||
size_t m_started = 0;
|
||||
size_t m_threads = 0;
|
||||
size_t m_ways = 0;
|
||||
|
@ -169,18 +164,17 @@ public:
|
|||
|
||||
rapidjson::Value hugePages(int version, rapidjson::Document &doc)
|
||||
{
|
||||
std::pair<unsigned, unsigned> pages(0, 0);
|
||||
HugePagesInfo pages;
|
||||
|
||||
# ifdef XMRIG_ALGO_RANDOMX
|
||||
if (algo.family() == Algorithm::RANDOM_X) {
|
||||
pages = Rx::hugePages();
|
||||
pages += Rx::hugePages();
|
||||
}
|
||||
# endif
|
||||
|
||||
mutex.lock();
|
||||
|
||||
pages.first += status.hugePages();
|
||||
pages.second += status.pages();
|
||||
pages += status.hugePages();
|
||||
|
||||
mutex.unlock();
|
||||
|
||||
|
@ -188,11 +182,11 @@ public:
|
|||
|
||||
if (version > 1) {
|
||||
hugepages.SetArray();
|
||||
hugepages.PushBack(pages.first, doc.GetAllocator());
|
||||
hugepages.PushBack(pages.second, doc.GetAllocator());
|
||||
hugepages.PushBack(static_cast<uint64_t>(pages.allocated), doc.GetAllocator());
|
||||
hugepages.PushBack(static_cast<uint64_t>(pages.total), doc.GetAllocator());
|
||||
}
|
||||
else {
|
||||
hugepages = pages.first == pages.second;
|
||||
hugepages = pages.isFullyAllocated();
|
||||
}
|
||||
|
||||
return hugepages;
|
||||
|
|
|
@ -119,10 +119,10 @@ std::vector<xmrig::CpuLaunchData> xmrig::CpuConfig::get(const Miner *miner, cons
|
|||
void xmrig::CpuConfig::read(const rapidjson::Value &value)
|
||||
{
|
||||
if (value.IsObject()) {
|
||||
m_enabled = Json::getBool(value, kEnabled, m_enabled);
|
||||
m_hugePages = Json::getBool(value, kHugePages, m_hugePages);
|
||||
m_limit = Json::getUint(value, kMaxThreadsHint, m_limit);
|
||||
m_yield = Json::getBool(value, kYield, m_yield);
|
||||
m_enabled = Json::getBool(value, kEnabled, m_enabled);
|
||||
m_hugePages = Json::getBool(value, kHugePages, m_hugePages);
|
||||
m_limit = Json::getUint(value, kMaxThreadsHint, m_limit);
|
||||
m_yield = Json::getBool(value, kYield, m_yield);
|
||||
|
||||
setAesMode(Json::getValue(value, kHwAes));
|
||||
setPriority(Json::getInt(value, kPriority, -1));
|
||||
|
|
|
@ -60,6 +60,7 @@ public:
|
|||
inline const String &argon2Impl() const { return m_argon2Impl; }
|
||||
inline const Threads<CpuThreads> &threads() const { return m_threads; }
|
||||
inline int priority() const { return m_priority; }
|
||||
inline uint32_t limit() const { return m_limit; }
|
||||
|
||||
private:
|
||||
void generate();
|
||||
|
|
|
@ -64,7 +64,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, true, m_node);
|
||||
m_memory = new VirtualMemory(m_algorithm.l3() * N, data.hugePages, false, true, m_node);
|
||||
}
|
||||
|
||||
|
||||
|
@ -97,7 +97,7 @@ void xmrig::CpuWorker<N>::allocateRandomX_VM()
|
|||
}
|
||||
|
||||
if (!m_vm) {
|
||||
m_vm = new RxVm(dataset, m_memory->scratchpad(), !m_hwAES);
|
||||
m_vm = new RxVm(dataset, m_memory->scratchpad(), !m_hwAES, m_assembly);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -37,6 +37,12 @@ namespace xmrig {
|
|||
class ICpuInfo
|
||||
{
|
||||
public:
|
||||
enum Vendor {
|
||||
VENDOR_UNKNOWN,
|
||||
VENDOR_INTEL,
|
||||
VENDOR_AMD
|
||||
};
|
||||
|
||||
virtual ~ICpuInfo() = default;
|
||||
|
||||
# if defined(__x86_64__) || defined(_M_AMD64) || defined (__arm64__) || defined (__aarch64__)
|
||||
|
@ -48,6 +54,7 @@ public:
|
|||
virtual Assembly::Id assembly() const = 0;
|
||||
virtual bool hasAES() const = 0;
|
||||
virtual bool hasAVX2() const = 0;
|
||||
virtual bool hasOneGbPages() const = 0;
|
||||
virtual const char *backend() const = 0;
|
||||
virtual const char *brand() const = 0;
|
||||
virtual CpuThreads threads(const Algorithm &algorithm, uint32_t limit) const = 0;
|
||||
|
@ -57,6 +64,7 @@ public:
|
|||
virtual size_t nodes() const = 0;
|
||||
virtual size_t packages() const = 0;
|
||||
virtual size_t threads() const = 0;
|
||||
virtual Vendor vendor() const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -22,6 +22,17 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "backend/cpu/platform/AdvancedCpuInfo.h"
|
||||
#include "3rdparty/libcpuid/libcpuid.h"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
#else
|
||||
# include <cpuid.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
|
@ -29,10 +40,6 @@
|
|||
#include <cstring>
|
||||
|
||||
|
||||
#include "3rdparty/libcpuid/libcpuid.h"
|
||||
#include "backend/cpu/platform/AdvancedCpuInfo.h"
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
|
@ -54,11 +61,38 @@ static inline void cpu_brand_string(char out[64], const char *in) {
|
|||
}
|
||||
|
||||
|
||||
static inline void cpuid(uint32_t level, int32_t output[4])
|
||||
{
|
||||
memset(output, 0, sizeof(int32_t) * 4);
|
||||
|
||||
# ifdef _MSC_VER
|
||||
__cpuid(output, static_cast<int>(level));
|
||||
# else
|
||||
__cpuid_count(level, 0, output[0], output[1], output[2], output[3]);
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
static inline bool has_feature(uint32_t level, uint32_t reg, int32_t bit)
|
||||
{
|
||||
int32_t cpu_info[4] = { 0 };
|
||||
cpuid(level, cpu_info);
|
||||
|
||||
return (cpu_info[reg] & bit) != 0;
|
||||
}
|
||||
|
||||
|
||||
static inline bool has_pdpe1gb()
|
||||
{
|
||||
return has_feature(0x80000001, 3, 1 << 26);
|
||||
}
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::AdvancedCpuInfo::AdvancedCpuInfo() :
|
||||
m_brand()
|
||||
m_pdpe1gb(has_pdpe1gb())
|
||||
{
|
||||
struct cpu_raw_data_t raw = {};
|
||||
struct cpu_id_t data = {};
|
||||
|
@ -69,21 +103,28 @@ xmrig::AdvancedCpuInfo::AdvancedCpuInfo() :
|
|||
cpu_brand_string(m_brand, data.brand_str);
|
||||
snprintf(m_backend, sizeof m_backend, "libcpuid/%s", cpuid_lib_version());
|
||||
|
||||
if (data.vendor == ::VENDOR_INTEL) {
|
||||
m_vendor = VENDOR_INTEL;
|
||||
}
|
||||
else if (data.vendor == ::VENDOR_AMD) {
|
||||
m_vendor = VENDOR_AMD;
|
||||
}
|
||||
|
||||
m_threads = static_cast<size_t>(data.total_logical_cpus);
|
||||
m_packages = std::max<size_t>(threads() / static_cast<size_t>(data.num_logical_cpus), 1);
|
||||
m_cores = static_cast<size_t>(data.num_cores) * m_packages;
|
||||
m_L3 = data.l3_cache > 0 ? static_cast<size_t>(data.l3_cache) * m_packages : 0;
|
||||
|
||||
const size_t l2 = static_cast<size_t>(data.l2_cache);
|
||||
const auto l2 = static_cast<size_t>(data.l2_cache);
|
||||
|
||||
// Workaround for AMD CPUs https://github.com/anrieff/libcpuid/issues/97
|
||||
if (data.vendor == VENDOR_AMD && data.ext_family >= 0x15 && data.ext_family < 0x17) {
|
||||
if (m_vendor == VENDOR_AMD && data.ext_family >= 0x15 && data.ext_family < 0x17) {
|
||||
m_L2 = l2 * (cores() / 2) * m_packages;
|
||||
m_L2_exclusive = true;
|
||||
}
|
||||
// Workaround for Intel Pentium Dual-Core, Core Duo, Core 2 Duo, Core 2 Quad and their Xeon homologue
|
||||
// These processors have L2 cache shared by 2 cores.
|
||||
else if (data.vendor == VENDOR_INTEL && data.ext_family == 0x06 && (data.ext_model == 0x0E || data.ext_model == 0x0F || data.ext_model == 0x17)) {
|
||||
else if (m_vendor == VENDOR_INTEL && data.ext_family == 0x06 && (data.ext_model == 0x0E || data.ext_model == 0x0F || data.ext_model == 0x17)) {
|
||||
size_t l2_count_per_socket = cores() > 1 ? cores() / 2 : 1;
|
||||
m_L2 = data.l2_cache > 0 ? l2 * l2_count_per_socket * m_packages : 0;
|
||||
}
|
||||
|
@ -97,10 +138,10 @@ xmrig::AdvancedCpuInfo::AdvancedCpuInfo() :
|
|||
if (data.flags[CPU_FEATURE_AES]) {
|
||||
m_aes = true;
|
||||
|
||||
if (data.vendor == VENDOR_AMD) {
|
||||
if (m_vendor == VENDOR_AMD) {
|
||||
m_assembly = (data.ext_family >= 23) ? Assembly::RYZEN : Assembly::BULLDOZER;
|
||||
}
|
||||
else if (data.vendor == VENDOR_INTEL) {
|
||||
else if (m_vendor == VENDOR_INTEL) {
|
||||
m_assembly = Assembly::INTEL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ protected:
|
|||
inline Assembly::Id assembly() const override { return m_assembly; }
|
||||
inline bool hasAES() const override { return m_aes; }
|
||||
inline bool hasAVX2() const override { return m_avx2; }
|
||||
inline bool hasOneGbPages() const override { return m_pdpe1gb; }
|
||||
inline const char *backend() const override { return m_backend; }
|
||||
inline const char *brand() const override { return m_brand; }
|
||||
inline size_t cores() const override { return m_cores; }
|
||||
|
@ -51,19 +52,22 @@ protected:
|
|||
inline size_t nodes() const override { return 0; }
|
||||
inline size_t packages() const override { return m_packages; }
|
||||
inline size_t threads() const override { return m_threads; }
|
||||
inline Vendor vendor() const override { return m_vendor; }
|
||||
|
||||
private:
|
||||
Assembly m_assembly;
|
||||
bool m_aes = false;
|
||||
bool m_avx2 = false;
|
||||
bool m_L2_exclusive = false;
|
||||
char m_backend[32];
|
||||
char m_brand[64 + 5];
|
||||
char m_backend[32]{};
|
||||
char m_brand[64 + 5]{};
|
||||
const bool m_pdpe1gb = false;
|
||||
size_t m_cores = 0;
|
||||
size_t m_L2 = 0;
|
||||
size_t m_L3 = 0;
|
||||
size_t m_packages = 1;
|
||||
size_t m_threads = 0;
|
||||
Vendor m_vendor = VENDOR_UNKNOWN;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
#include <cstring>
|
||||
#include <thread>
|
||||
|
||||
|
||||
|
@ -45,6 +45,10 @@
|
|||
# define bit_AVX2 (1 << 5)
|
||||
#endif
|
||||
|
||||
#ifndef bit_PDPE1GB
|
||||
# define bit_PDPE1GB (1 << 26)
|
||||
#endif
|
||||
|
||||
|
||||
#include "backend/cpu/platform/BasicCpuInfo.h"
|
||||
#include "crypto/common/Assembly.h"
|
||||
|
@ -53,6 +57,7 @@
|
|||
#define VENDOR_ID (0)
|
||||
#define PROCESSOR_INFO (1)
|
||||
#define EXTENDED_FEATURES (7)
|
||||
#define PROCESSOR_EXT_INFO (0x80000001)
|
||||
#define PROCESSOR_BRAND_STRING_1 (0x80000002)
|
||||
#define PROCESSOR_BRAND_STRING_2 (0x80000003)
|
||||
#define PROCESSOR_BRAND_STRING_3 (0x80000004)
|
||||
|
@ -108,7 +113,7 @@ static void cpu_brand_string(char out[64 + 6]) {
|
|||
}
|
||||
|
||||
|
||||
static bool has_feature(uint32_t level, uint32_t reg, int32_t bit)
|
||||
static inline bool has_feature(uint32_t level, uint32_t reg, int32_t bit)
|
||||
{
|
||||
int32_t cpu_info[4] = { 0 };
|
||||
cpuid(level, cpu_info);
|
||||
|
@ -136,15 +141,20 @@ static inline bool has_avx2()
|
|||
}
|
||||
|
||||
|
||||
static inline bool has_pdpe1gb()
|
||||
{
|
||||
return has_feature(PROCESSOR_EXT_INFO, EDX_Reg, bit_PDPE1GB);
|
||||
}
|
||||
|
||||
|
||||
} // namespace xmrig
|
||||
|
||||
|
||||
xmrig::BasicCpuInfo::BasicCpuInfo() :
|
||||
m_brand(),
|
||||
m_threads(std::thread::hardware_concurrency()),
|
||||
m_assembly(Assembly::NONE),
|
||||
m_aes(has_aes_ni()),
|
||||
m_avx2(has_avx2())
|
||||
m_avx2(has_avx2()),
|
||||
m_pdpe1gb(has_pdpe1gb())
|
||||
{
|
||||
cpu_brand_string(m_brand);
|
||||
|
||||
|
@ -160,12 +170,15 @@ xmrig::BasicCpuInfo::BasicCpuInfo() :
|
|||
memcpy(vendor + 8, &data[2], 4);
|
||||
|
||||
if (memcmp(vendor, "AuthenticAMD", 12) == 0) {
|
||||
m_vendor = VENDOR_AMD;
|
||||
|
||||
cpuid(PROCESSOR_INFO, data);
|
||||
const int32_t family = get_masked(data[EAX_Reg], 12, 8) + get_masked(data[EAX_Reg], 28, 20);
|
||||
|
||||
m_assembly = family >= 23 ? Assembly::RYZEN : Assembly::BULLDOZER;
|
||||
}
|
||||
else {
|
||||
else if (memcmp(vendor, "GenuineIntel", 12) == 0) {
|
||||
m_vendor = VENDOR_INTEL;
|
||||
m_assembly = Assembly::INTEL;
|
||||
}
|
||||
}
|
||||
|
@ -179,7 +192,7 @@ const char *xmrig::BasicCpuInfo::backend() const
|
|||
}
|
||||
|
||||
|
||||
xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm, uint32_t limit) const
|
||||
xmrig::CpuThreads xmrig::BasicCpuInfo::threads(const Algorithm &algorithm, uint32_t) const
|
||||
{
|
||||
const size_t count = std::thread::hardware_concurrency();
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ protected:
|
|||
inline Assembly::Id assembly() const override { return m_assembly; }
|
||||
inline bool hasAES() const override { return m_aes; }
|
||||
inline bool hasAVX2() const override { return m_avx2; }
|
||||
inline bool hasOneGbPages() const override { return m_pdpe1gb; }
|
||||
inline const char *brand() const override { return m_brand; }
|
||||
inline size_t cores() const override { return 0; }
|
||||
inline size_t L2() const override { return 0; }
|
||||
|
@ -51,15 +52,18 @@ protected:
|
|||
inline size_t nodes() const override { return 0; }
|
||||
inline size_t packages() const override { return 1; }
|
||||
inline size_t threads() const override { return m_threads; }
|
||||
inline Vendor vendor() const override { return m_vendor; }
|
||||
|
||||
protected:
|
||||
char m_brand[64 + 6];
|
||||
char m_brand[64 + 6]{};
|
||||
size_t m_threads;
|
||||
|
||||
private:
|
||||
Assembly m_assembly;
|
||||
bool m_aes;
|
||||
const bool m_avx2;
|
||||
Assembly m_assembly = Assembly::NONE;
|
||||
bool m_aes = false;
|
||||
const bool m_avx2 = false;
|
||||
const bool m_pdpe1gb = false;
|
||||
Vendor m_vendor = VENDOR_UNKNOWN;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <cstring>
|
||||
#include <thread>
|
||||
|
||||
|
||||
|
@ -36,10 +36,7 @@
|
|||
|
||||
|
||||
xmrig::BasicCpuInfo::BasicCpuInfo() :
|
||||
m_brand(),
|
||||
m_threads(std::thread::hardware_concurrency()),
|
||||
m_aes(false),
|
||||
m_avx2(false)
|
||||
m_threads(std::thread::hardware_concurrency())
|
||||
{
|
||||
# ifdef XMRIG_ARMv8
|
||||
memcpy(m_brand, "ARMv8", 5);
|
||||
|
|
|
@ -262,7 +262,7 @@ xmrig::CpuThreads xmrig::HwlocCpuInfo::threads(const Algorithm &algorithm, uint3
|
|||
|
||||
void xmrig::HwlocCpuInfo::processTopLevelCache(hwloc_obj_t cache, const Algorithm &algorithm, CpuThreads &threads, size_t limit) const
|
||||
{
|
||||
constexpr size_t oneMiB = 1024u * 1024u;
|
||||
constexpr size_t oneMiB = 1024U * 1024U;
|
||||
|
||||
size_t PUs = countByType(cache, HWLOC_OBJ_PU);
|
||||
if (PUs == 0) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue