This commit is contained in:
MoneroOcean 2019-12-14 09:24:11 -08:00
commit 01e2945ab7
125 changed files with 4772 additions and 2073 deletions

View file

@ -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;

View file

@ -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));

View file

@ -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();

View file

@ -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

View file

@ -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;
};

View file

@ -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;
}
}

View file

@ -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;
};

View file

@ -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();

View file

@ -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;
};

View file

@ -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);

View file

@ -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) {