Merge xmrig v6.7.0 into master
This commit is contained in:
commit
1719879f7e
249 changed files with 6814 additions and 6134 deletions
|
@ -173,7 +173,7 @@ void sort_indices(int N, const uint8_t* v, uint64_t* indices, uint64_t* tmp_indi
|
|||
|
||||
bool xmrig::astrobwt::astrobwt_dero(const void* input_data, uint32_t input_size, void* scratchpad, uint8_t* output_hash, int stage2_max_size, bool avx2)
|
||||
{
|
||||
uint8_t key[32];
|
||||
alignas(8) uint8_t key[32];
|
||||
uint8_t* scratchpad_ptr = (uint8_t*)(scratchpad) + 64;
|
||||
uint8_t* stage1_output = scratchpad_ptr;
|
||||
uint8_t* stage2_output = scratchpad_ptr;
|
||||
|
|
|
@ -219,7 +219,7 @@ static void patchAsmVariants()
|
|||
patchCode(cn_double_double_mainloop_sandybridge_asm, cnv2_double_mainloop_sandybridge_asm, ITER);
|
||||
}
|
||||
|
||||
VirtualMemory::protectExecutableMemory(base, allocation_size);
|
||||
VirtualMemory::protectRX(base, allocation_size);
|
||||
VirtualMemory::flushInstructionCache(base, allocation_size);
|
||||
}
|
||||
} // namespace xmrig
|
||||
|
|
|
@ -76,7 +76,7 @@ static inline void add_random_math(uint8_t* &p, const V4_Instruction* code, int
|
|||
|
||||
void_func begin = instructions[c];
|
||||
|
||||
if ((ASM = xmrig::Assembly::BULLDOZER) && (inst.opcode == MUL) && !is_64_bit) {
|
||||
if ((ASM == xmrig::Assembly::BULLDOZER) && (inst.opcode == MUL) && !is_64_bit) {
|
||||
// AMD Bulldozer has latency 4 for 32-bit IMUL and 6 for 64-bit IMUL
|
||||
// Always use 32-bit IMUL for AMD Bulldozer in 32-bit mode - skip prefix 0x48 and change 0x49 to 0x41
|
||||
uint8_t* prefix = reinterpret_cast<uint8_t*>(begin);
|
||||
|
|
|
@ -1,13 +1,6 @@
|
|||
/* 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 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
@ -24,8 +17,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
/* 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-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
@ -57,6 +51,7 @@ public:
|
|||
rapidjson::Value toJSON() const;
|
||||
|
||||
inline bool isEqual(const Assembly &other) const { return m_id == other.m_id; }
|
||||
inline Id id() const { return m_id; }
|
||||
|
||||
inline bool operator!=(Assembly::Id id) const { return m_id != id; }
|
||||
inline bool operator!=(const Assembly &other) const { return !isEqual(other); }
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
/* 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 tevador <tevador@gmail.com>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2020 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
/* 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 tevador <tevador@gmail.com>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2020 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
@ -49,17 +42,22 @@ public:
|
|||
VirtualMemory(size_t size, bool hugePages, bool oneGbPages, bool usePool, uint32_t node = 0, size_t alignSize = 64);
|
||||
~VirtualMemory();
|
||||
|
||||
inline bool isHugePages() const { return m_flags.test(FLAG_HUGEPAGES); }
|
||||
inline bool isOneGbPages() const { return m_flags.test(FLAG_1GB_PAGES); }
|
||||
inline size_t size() const { return m_size; }
|
||||
inline size_t capacity() const { return m_capacity; }
|
||||
inline uint8_t *raw() const { return m_scratchpad; }
|
||||
inline uint8_t *scratchpad() const { return m_scratchpad; }
|
||||
inline bool isHugePages() const { return m_flags.test(FLAG_HUGEPAGES); }
|
||||
inline bool isOneGbPages() const { return m_flags.test(FLAG_1GB_PAGES); }
|
||||
inline size_t size() const { return m_size; }
|
||||
inline size_t capacity() const { return m_capacity; }
|
||||
inline uint8_t *raw() const { return m_scratchpad; }
|
||||
inline uint8_t *scratchpad() const { return m_scratchpad; }
|
||||
|
||||
inline static void flushInstructionCache(void *p1, void *p2) { flushInstructionCache(p1, static_cast<uint8_t*>(p2) - static_cast<uint8_t*>(p1)); }
|
||||
|
||||
HugePagesInfo hugePages() const;
|
||||
|
||||
static bool isHugepagesAvailable();
|
||||
static bool isOneGbPagesAvailable();
|
||||
static bool protectRW(void *p, size_t size);
|
||||
static bool protectRWX(void *p, size_t size);
|
||||
static bool protectRX(void *p, size_t size);
|
||||
static uint32_t bindToNUMANode(int64_t affinity);
|
||||
static void *allocateExecutableMemory(size_t size, bool hugePages);
|
||||
static void *allocateLargePagesMemory(size_t size);
|
||||
|
@ -68,8 +66,6 @@ public:
|
|||
static void flushInstructionCache(void *p, size_t size);
|
||||
static void freeLargePagesMemory(void *p, size_t size);
|
||||
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 constexpr size_t align(size_t pos, size_t align = 2097152) { return ((pos - 1) / align + 1) * align; }
|
||||
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
/* 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>
|
||||
* Copyright (c) 2018-2020 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
@ -34,8 +27,18 @@
|
|||
#include "crypto/common/VirtualMemory.h"
|
||||
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#ifdef XMRIG_OS_APPLE
|
||||
# include <libkern/OSCacheControl.h>
|
||||
# include <mach/vm_statistics.h>
|
||||
# include <pthread.h>
|
||||
# include <TargetConditionals.h>
|
||||
# ifdef XMRIG_ARM
|
||||
# define MEXTRA MAP_JIT
|
||||
# else
|
||||
# define MEXTRA 0
|
||||
# endif
|
||||
#else
|
||||
# define MEXTRA 0
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -47,9 +50,20 @@
|
|||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_SECURE_JIT
|
||||
# define SECURE_PROT_EXEC 0
|
||||
#else
|
||||
# define SECURE_PROT_EXEC PROT_EXEC
|
||||
#endif
|
||||
|
||||
|
||||
bool xmrig::VirtualMemory::isHugepagesAvailable()
|
||||
{
|
||||
# if defined(XMRIG_OS_MACOS) && defined(XMRIG_ARM)
|
||||
return false;
|
||||
# else
|
||||
return true;
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,19 +77,51 @@ bool xmrig::VirtualMemory::isOneGbPagesAvailable()
|
|||
}
|
||||
|
||||
|
||||
bool xmrig::VirtualMemory::protectRW(void *p, size_t size)
|
||||
{
|
||||
# if defined(XMRIG_OS_APPLE) && defined(XMRIG_ARM)
|
||||
pthread_jit_write_protect_np(false);
|
||||
return true;
|
||||
# else
|
||||
return mprotect(p, size, PROT_READ | PROT_WRITE) == 0;
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::VirtualMemory::protectRWX(void *p, size_t size)
|
||||
{
|
||||
return mprotect(p, size, PROT_READ | PROT_WRITE | PROT_EXEC) == 0;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::VirtualMemory::protectRX(void *p, size_t size)
|
||||
{
|
||||
# if defined(XMRIG_OS_APPLE) && defined(XMRIG_ARM)
|
||||
pthread_jit_write_protect_np(true);
|
||||
flushInstructionCache(p, size);
|
||||
return true;
|
||||
# else
|
||||
return mprotect(p, size, PROT_READ | PROT_EXEC) == 0;
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
void *xmrig::VirtualMemory::allocateExecutableMemory(size_t size, bool hugePages)
|
||||
{
|
||||
# if defined(__APPLE__)
|
||||
void *mem = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
# if defined(XMRIG_OS_APPLE)
|
||||
void *mem = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON | MEXTRA, -1, 0);
|
||||
# ifdef XMRIG_ARM
|
||||
pthread_jit_write_protect_np(false);
|
||||
# endif
|
||||
# elif defined(__FreeBSD__)
|
||||
void *mem = nullptr;
|
||||
|
||||
if (hugePages) {
|
||||
mem = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0);
|
||||
mem = mmap(0, size, PROT_READ | PROT_WRITE | SECURE_PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER | MAP_PREFAULT_READ, -1, 0);
|
||||
}
|
||||
|
||||
if (!mem) {
|
||||
mem = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
mem = mmap(0, size, PROT_READ | PROT_WRITE | SECURE_PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
}
|
||||
|
||||
# else
|
||||
|
@ -91,11 +137,11 @@ void *xmrig::VirtualMemory::allocateExecutableMemory(size_t size, bool hugePages
|
|||
void *mem = nullptr;
|
||||
|
||||
if (hugePages) {
|
||||
mem = mmap(0, align(size), PROT_READ | PROT_WRITE | 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 | flag_2mb, -1, 0);
|
||||
}
|
||||
|
||||
if (!mem) {
|
||||
mem = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
mem = mmap(0, size, PROT_READ | PROT_WRITE | SECURE_PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
}
|
||||
|
||||
# endif
|
||||
|
@ -152,7 +198,9 @@ void *xmrig::VirtualMemory::allocateOneGbPagesMemory(size_t size)
|
|||
|
||||
void xmrig::VirtualMemory::flushInstructionCache(void *p, size_t size)
|
||||
{
|
||||
# ifdef HAVE_BUILTIN_CLEAR_CACHE
|
||||
# if defined(XMRIG_OS_APPLE)
|
||||
sys_icache_invalidate(p, size);
|
||||
# elif defined (HAVE_BUILTIN_CLEAR_CACHE) || defined (__GNUC__)
|
||||
__builtin___clear_cache(reinterpret_cast<char*>(p), reinterpret_cast<char*>(p) + size);
|
||||
# endif
|
||||
}
|
||||
|
@ -164,18 +212,6 @@ void xmrig::VirtualMemory::freeLargePagesMemory(void *p, size_t size)
|
|||
}
|
||||
|
||||
|
||||
void xmrig::VirtualMemory::protectExecutableMemory(void *p, size_t size)
|
||||
{
|
||||
mprotect(p, size, PROT_READ | PROT_EXEC);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::VirtualMemory::unprotectExecutableMemory(void *p, size_t size)
|
||||
{
|
||||
mprotect(p, size, PROT_WRITE | PROT_EXEC);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::VirtualMemory::osInit(bool)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
/* 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>
|
||||
* Copyright (c) 2018-2020 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
@ -36,6 +29,13 @@
|
|||
#include "crypto/common/VirtualMemory.h"
|
||||
|
||||
|
||||
#ifdef XMRIG_SECURE_JIT
|
||||
# define SECURE_PAGE_EXECUTE_READWRITE PAGE_READWRITE
|
||||
#else
|
||||
# define SECURE_PAGE_EXECUTE_READWRITE PAGE_EXECUTE_READWRITE
|
||||
#endif
|
||||
|
||||
|
||||
namespace xmrig {
|
||||
|
||||
|
||||
|
@ -63,7 +63,7 @@ Return value: TRUE indicates success, FALSE failure.
|
|||
static BOOL SetLockPagesPrivilege() {
|
||||
HANDLE token;
|
||||
|
||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token) != TRUE) {
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -71,12 +71,12 @@ static BOOL SetLockPagesPrivilege() {
|
|||
tp.PrivilegeCount = 1;
|
||||
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
|
||||
if (LookupPrivilegeValue(nullptr, SE_LOCK_MEMORY_NAME, &(tp.Privileges[0].Luid)) != TRUE) {
|
||||
if (!LookupPrivilegeValue(nullptr, SE_LOCK_MEMORY_NAME, &(tp.Privileges[0].Luid))) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL rc = AdjustTokenPrivileges(token, FALSE, (PTOKEN_PRIVILEGES) &tp, 0, nullptr, nullptr);
|
||||
if (rc != TRUE || GetLastError() != ERROR_SUCCESS) {
|
||||
if (!rc || GetLastError() != ERROR_SUCCESS) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ static BOOL ObtainLockPagesPrivilege() {
|
|||
HANDLE token;
|
||||
PTOKEN_USER user = nullptr;
|
||||
|
||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) == TRUE) {
|
||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) {
|
||||
DWORD size = 0;
|
||||
|
||||
GetTokenInformation(token, TokenUser, nullptr, 0, &size);
|
||||
|
@ -162,16 +162,40 @@ bool xmrig::VirtualMemory::isOneGbPagesAvailable()
|
|||
}
|
||||
|
||||
|
||||
bool xmrig::VirtualMemory::protectRW(void *p, size_t size)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
|
||||
return VirtualProtect(p, size, PAGE_READWRITE, &oldProtect) != 0;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::VirtualMemory::protectRWX(void *p, size_t size)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
|
||||
return VirtualProtect(p, size, PAGE_EXECUTE_READWRITE, &oldProtect) != 0;
|
||||
}
|
||||
|
||||
|
||||
bool xmrig::VirtualMemory::protectRX(void *p, size_t size)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
|
||||
return VirtualProtect(p, size, PAGE_EXECUTE_READ, &oldProtect) != 0;
|
||||
}
|
||||
|
||||
|
||||
void *xmrig::VirtualMemory::allocateExecutableMemory(size_t size, bool hugePages)
|
||||
{
|
||||
void* result = nullptr;
|
||||
|
||||
if (hugePages) {
|
||||
result = VirtualAlloc(nullptr, align(size), MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_EXECUTE_READWRITE);
|
||||
result = VirtualAlloc(nullptr, align(size), MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, SECURE_PAGE_EXECUTE_READWRITE);
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
result = VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||
result = VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, SECURE_PAGE_EXECUTE_READWRITE);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -209,20 +233,6 @@ void xmrig::VirtualMemory::freeLargePagesMemory(void *p, size_t)
|
|||
}
|
||||
|
||||
|
||||
void xmrig::VirtualMemory::protectExecutableMemory(void *p, size_t size)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(p, size, PAGE_EXECUTE_READ, &oldProtect);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::VirtualMemory::unprotectExecutableMemory(void *p, size_t size)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(p, size, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
}
|
||||
|
||||
|
||||
void xmrig::VirtualMemory::osInit(bool hugePages)
|
||||
{
|
||||
if (hugePages) {
|
||||
|
|
|
@ -28,12 +28,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
#include "crypto/randomx/aes_hash.hpp"
|
||||
#include "crypto/randomx/soft_aes.h"
|
||||
#include "crypto/randomx/randomx.h"
|
||||
#include "base/tools/Chrono.h"
|
||||
#include "base/tools/Profiler.h"
|
||||
#include "crypto/randomx/randomx.h"
|
||||
#include "crypto/randomx/soft_aes.h"
|
||||
#include "crypto/rx/Profiler.h"
|
||||
|
||||
#define AES_HASH_1R_STATE0 0xd7983aad, 0xcc82db47, 0x9fa856de, 0x92b52c0d
|
||||
#define AES_HASH_1R_STATE1 0xace78057, 0xf59e125a, 0x15c7b798, 0x338d996e
|
||||
|
@ -371,7 +372,7 @@ hashAndFillAes1Rx4_impl* softAESImpl = &hashAndFillAes1Rx4<1,1>;
|
|||
void SelectSoftAESImpl(size_t threadsCount)
|
||||
{
|
||||
constexpr int test_length_ms = 100;
|
||||
const std::vector<hashAndFillAes1Rx4_impl *> impl = {
|
||||
const std::array<hashAndFillAes1Rx4_impl *, 4> impl = {
|
||||
&hashAndFillAes1Rx4<1,1>,
|
||||
&hashAndFillAes1Rx4<2,1>,
|
||||
&hashAndFillAes1Rx4<2,2>,
|
||||
|
|
28
src/crypto/randomx/asm/program_sshash_avx2_constants.inc
Normal file
28
src/crypto/randomx/asm/program_sshash_avx2_constants.inc
Normal file
|
@ -0,0 +1,28 @@
|
|||
r0_avx2_increments:
|
||||
db 2,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0
|
||||
mul_hi_avx2_data:
|
||||
db 0,0,0,0,1,0,0,0
|
||||
r0_avx2_mul:
|
||||
;#/ 6364136223846793005
|
||||
db 45, 127, 149, 76, 45, 244, 81, 88
|
||||
r1_avx2_add:
|
||||
;#/ 9298411001130361340
|
||||
db 252, 161, 245, 89, 138, 151, 10, 129
|
||||
r2_avx2_add:
|
||||
;#/ 12065312585734608966
|
||||
db 70, 216, 194, 56, 223, 153, 112, 167
|
||||
r3_avx2_add:
|
||||
;#/ 9306329213124626780
|
||||
db 92, 73, 34, 191, 28, 185, 38, 129
|
||||
r4_avx2_add:
|
||||
;#/ 5281919268842080866
|
||||
db 98, 138, 159, 23, 151, 37, 77, 73
|
||||
r5_avx2_add:
|
||||
;#/ 10536153434571861004
|
||||
db 12, 236, 170, 206, 185, 239, 55, 146
|
||||
r6_avx2_add:
|
||||
;#/ 3398623926847679864
|
||||
db 120, 45, 230, 108, 116, 86, 42, 47
|
||||
r7_avx2_add:
|
||||
;#/ 9549104520008361294
|
||||
db 78, 229, 44, 182, 247, 59, 133, 132
|
31
src/crypto/randomx/asm/program_sshash_avx2_epilogue.inc
Normal file
31
src/crypto/randomx/asm/program_sshash_avx2_epilogue.inc
Normal file
|
@ -0,0 +1,31 @@
|
|||
add rsp, 40
|
||||
pop r9
|
||||
|
||||
movdqu xmm0, xmmword ptr [rsp]
|
||||
movdqu xmm1, xmmword ptr [rsp + 16]
|
||||
movdqu xmm2, xmmword ptr [rsp + 32]
|
||||
movdqu xmm3, xmmword ptr [rsp + 48]
|
||||
movdqu xmm4, xmmword ptr [rsp + 64]
|
||||
movdqu xmm5, xmmword ptr [rsp + 80]
|
||||
movdqu xmm6, xmmword ptr [rsp + 96]
|
||||
movdqu xmm7, xmmword ptr [rsp + 112]
|
||||
movdqu xmm8, xmmword ptr [rsp + 128]
|
||||
movdqu xmm9, xmmword ptr [rsp + 144]
|
||||
movdqu xmm10, xmmword ptr [rsp + 160]
|
||||
movdqu xmm11, xmmword ptr [rsp + 176]
|
||||
movdqu xmm12, xmmword ptr [rsp + 192]
|
||||
movdqu xmm13, xmmword ptr [rsp + 208]
|
||||
movdqu xmm14, xmmword ptr [rsp + 224]
|
||||
movdqu xmm15, xmmword ptr [rsp + 240]
|
||||
vzeroupper
|
||||
add rsp, 256
|
||||
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
pop r12
|
||||
pop rsi
|
||||
pop rdi
|
||||
pop rbp
|
||||
pop rbx
|
||||
ret
|
37
src/crypto/randomx/asm/program_sshash_avx2_loop_begin.inc
Normal file
37
src/crypto/randomx/asm/program_sshash_avx2_loop_begin.inc
Normal file
|
@ -0,0 +1,37 @@
|
|||
;# prefetch RandomX dataset lines
|
||||
prefetchnta byte ptr [rsi]
|
||||
prefetchnta byte ptr [rsi+64]
|
||||
prefetchnta byte ptr [rsi+128]
|
||||
prefetchnta byte ptr [rsi+192]
|
||||
prefetchnta byte ptr [rsi+256]
|
||||
|
||||
;# prefetch RandomX cache lines
|
||||
mov rbx, rbp
|
||||
and rbx, RANDOMX_CACHE_MASK
|
||||
shl rbx, 6
|
||||
add rbx, rdi
|
||||
prefetchnta byte ptr [rbx]
|
||||
lea rax, [rbp+1]
|
||||
and rax, RANDOMX_CACHE_MASK
|
||||
shl rax, 6
|
||||
add rax, rdi
|
||||
prefetchnta byte ptr [rax]
|
||||
mov [rsp], rax
|
||||
lea rax, [rbp+2]
|
||||
and rax, RANDOMX_CACHE_MASK
|
||||
shl rax, 6
|
||||
add rax, rdi
|
||||
prefetchnta byte ptr [rax]
|
||||
mov [rsp+8], rax
|
||||
lea rax, [rbp+3]
|
||||
and rax, RANDOMX_CACHE_MASK
|
||||
shl rax, 6
|
||||
add rax, rdi
|
||||
prefetchnta byte ptr [rax]
|
||||
mov [rsp+16], rax
|
||||
lea rax, [rbp+4]
|
||||
and rax, RANDOMX_CACHE_MASK
|
||||
shl rax, 6
|
||||
add rax, rdi
|
||||
prefetchnta byte ptr [rax]
|
||||
mov [rsp+24], rax
|
38
src/crypto/randomx/asm/program_sshash_avx2_loop_end.inc
Normal file
38
src/crypto/randomx/asm/program_sshash_avx2_loop_end.inc
Normal file
|
@ -0,0 +1,38 @@
|
|||
mov qword ptr [rsi+0], r8
|
||||
vpunpcklqdq ymm8, ymm0, ymm1
|
||||
mov qword ptr [rsi+8], r9
|
||||
vpunpcklqdq ymm9, ymm2, ymm3
|
||||
mov qword ptr [rsi+16], r10
|
||||
vpunpcklqdq ymm10, ymm4, ymm5
|
||||
mov qword ptr [rsi+24], r11
|
||||
vpunpcklqdq ymm11, ymm6, ymm7
|
||||
mov qword ptr [rsi+32], r12
|
||||
vpunpckhqdq ymm12, ymm0, ymm1
|
||||
mov qword ptr [rsi+40], r13
|
||||
vpunpckhqdq ymm13, ymm2, ymm3
|
||||
mov qword ptr [rsi+48], r14
|
||||
vpunpckhqdq ymm14, ymm4, ymm5
|
||||
mov qword ptr [rsi+56], r15
|
||||
vpunpckhqdq ymm15, ymm6, ymm7
|
||||
|
||||
vperm2i128 ymm0, ymm8, ymm9, 32
|
||||
vperm2i128 ymm1, ymm10, ymm11, 32
|
||||
vmovdqu ymmword ptr [rsi+64], ymm0
|
||||
vmovdqu ymmword ptr [rsi+96], ymm1
|
||||
vperm2i128 ymm2, ymm12, ymm13, 32
|
||||
vperm2i128 ymm3, ymm14, ymm15, 32
|
||||
vmovdqu ymmword ptr [rsi+128], ymm2
|
||||
vmovdqu ymmword ptr [rsi+160], ymm3
|
||||
vperm2i128 ymm4, ymm8, ymm9, 49
|
||||
vperm2i128 ymm5, ymm10, ymm11, 49
|
||||
vmovdqu ymmword ptr [rsi+192], ymm4
|
||||
vmovdqu ymmword ptr [rsi+224], ymm5
|
||||
vperm2i128 ymm6, ymm12, ymm13, 49
|
||||
vperm2i128 ymm7, ymm14, ymm15, 49
|
||||
vmovdqu ymmword ptr [rsi+256], ymm6
|
||||
vmovdqu ymmword ptr [rsi+288], ymm7
|
||||
|
||||
add rbp, 5
|
||||
add rsi, 320
|
||||
cmp rbp, qword ptr [rsp+40]
|
||||
db 15, 130, 0, 0, 0, 0 ;# jb rel32
|
|
@ -0,0 +1,27 @@
|
|||
push rbx
|
||||
push rbp
|
||||
push rdi
|
||||
push rsi
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
|
||||
;# save all XMM registers just to be safe for all calling conventions
|
||||
sub rsp, 256
|
||||
movdqu xmmword ptr [rsp], xmm0
|
||||
movdqu xmmword ptr [rsp + 16], xmm1
|
||||
movdqu xmmword ptr [rsp + 32], xmm2
|
||||
movdqu xmmword ptr [rsp + 48], xmm3
|
||||
movdqu xmmword ptr [rsp + 64], xmm4
|
||||
movdqu xmmword ptr [rsp + 80], xmm5
|
||||
movdqu xmmword ptr [rsp + 96], xmm6
|
||||
movdqu xmmword ptr [rsp + 112], xmm7
|
||||
movdqu xmmword ptr [rsp + 128], xmm8
|
||||
movdqu xmmword ptr [rsp + 144], xmm9
|
||||
movdqu xmmword ptr [rsp + 160], xmm10
|
||||
movdqu xmmword ptr [rsp + 176], xmm11
|
||||
movdqu xmmword ptr [rsp + 192], xmm12
|
||||
movdqu xmmword ptr [rsp + 208], xmm13
|
||||
movdqu xmmword ptr [rsp + 224], xmm14
|
||||
movdqu xmmword ptr [rsp + 240], xmm15
|
50
src/crypto/randomx/asm/program_sshash_avx2_ssh_load.inc
Normal file
50
src/crypto/randomx/asm/program_sshash_avx2_ssh_load.inc
Normal file
|
@ -0,0 +1,50 @@
|
|||
sub rsp, 40
|
||||
mov [rsp], rbx
|
||||
vmovdqu ymmword ptr [rsp+8], ymm14
|
||||
|
||||
mov rax, [rsp+40]
|
||||
mov rbx, [rsp+48]
|
||||
mov rcx, [rsp+56]
|
||||
mov rdx, [rsp+64]
|
||||
|
||||
vmovdqu ymm8, ymmword ptr [rax] ;# ymm8 = r0[1], r1[1], r2[1], r3[1]
|
||||
vmovdqu ymm9, ymmword ptr [rbx] ;# ymm9 = r0[2], r1[2], r2[2], r3[2]
|
||||
vmovdqu ymm10, ymmword ptr [rcx] ;# ymm10 = r0[3], r1[3], r2[3], r3[3]
|
||||
vmovdqu ymm11, ymmword ptr [rdx] ;# ymm11 = r0[4], r1[4], r2[4], r3[4]
|
||||
|
||||
vpunpcklqdq ymm12, ymm8, ymm9 ;# ymm12 = r0[1], r0[2], r2[1], r2[2]
|
||||
vpunpcklqdq ymm13, ymm10, ymm11 ;# ymm13 = r0[3], r0[4], r2[3], r2[4]
|
||||
vperm2i128 ymm14, ymm12, ymm13, 32 ;# ymm14 = r0[1], r0[2], r0[3], r0[4]
|
||||
vpxor ymm0, ymm0, ymm14
|
||||
vperm2i128 ymm14, ymm12, ymm13, 49 ;# ymm14 = r2[1], r2[2], r2[3], r2[4]
|
||||
vpxor ymm2, ymm2, ymm14
|
||||
|
||||
vpunpckhqdq ymm12, ymm8, ymm9 ;# ymm12 = r1[1], r1[2], r3[1], r3[2]
|
||||
vpunpckhqdq ymm13, ymm10, ymm11 ;# ymm13 = r1[3], r1[4], r3[3], r3[4]
|
||||
vperm2i128 ymm14, ymm12, ymm13, 32 ;# ymm14 = r1[1], r1[2], r1[3], r1[4]
|
||||
vpxor ymm1, ymm1, ymm14
|
||||
vperm2i128 ymm14, ymm12, ymm13, 49 ;# ymm14 = r3[1], r3[2], r3[3], r3[4]
|
||||
vpxor ymm3, ymm3, ymm14
|
||||
|
||||
vmovdqu ymm8, ymmword ptr [rax+32] ;# ymm8 = r4[1], r5[1], r6[1], r7[1]
|
||||
vmovdqu ymm9, ymmword ptr [rbx+32] ;# ymm9 = r4[2], r5[2], r6[2], r7[2]
|
||||
vmovdqu ymm10, ymmword ptr [rcx+32] ;# ymm10 = r4[3], r5[3], r6[3], r7[3]
|
||||
vmovdqu ymm11, ymmword ptr [rdx+32] ;# ymm11 = r4[4], r5[4], r6[4], r7[4]
|
||||
|
||||
vpunpcklqdq ymm12, ymm8, ymm9 ;# ymm12 = r4[1], r4[2], r6[1], r6[2]
|
||||
vpunpcklqdq ymm13, ymm10, ymm11 ;# ymm13 = r4[3], r4[4], r6[3], r6[4]
|
||||
vperm2i128 ymm14, ymm12, ymm13, 32 ;# ymm14 = r4[1], r4[2], r4[3], r4[4]
|
||||
vpxor ymm4, ymm4, ymm14
|
||||
vperm2i128 ymm14, ymm12, ymm13, 49 ;# ymm14 = r6[1], r6[2], r6[3], r6[4]
|
||||
vpxor ymm6, ymm6, ymm14
|
||||
|
||||
vpunpckhqdq ymm12, ymm8, ymm9 ;# ymm12 = r5[1], r5[2], r7[1], r7[2]
|
||||
vpunpckhqdq ymm13, ymm10, ymm11 ;# ymm13 = r5[3], r5[4], r7[3], r7[4]
|
||||
vperm2i128 ymm14, ymm12, ymm13, 32 ;# ymm14 = r5[1], r5[2], r5[3], r5[4]
|
||||
vpxor ymm5, ymm5, ymm14
|
||||
vperm2i128 ymm14, ymm12, ymm13, 49 ;# ymm14 = r7[1], r7[2], r7[3], r7[4]
|
||||
vpxor ymm7, ymm7, ymm14
|
||||
|
||||
mov rbx, [rsp]
|
||||
vmovdqu ymm14, ymmword ptr [rsp+8]
|
||||
add rsp, 40
|
29
src/crypto/randomx/asm/program_sshash_avx2_ssh_prefetch.inc
Normal file
29
src/crypto/randomx/asm/program_sshash_avx2_ssh_prefetch.inc
Normal file
|
@ -0,0 +1,29 @@
|
|||
vmovdqu ymmword ptr [rsp], ymm0
|
||||
|
||||
mov rax, [rsp]
|
||||
and rax, RANDOMX_CACHE_MASK
|
||||
shl rax, 6
|
||||
add rax, rdi
|
||||
mov [rsp], rax
|
||||
prefetchnta byte ptr [rax]
|
||||
|
||||
mov rax, [rsp+8]
|
||||
and rax, RANDOMX_CACHE_MASK
|
||||
shl rax, 6
|
||||
add rax, rdi
|
||||
mov [rsp+8], rax
|
||||
prefetchnta byte ptr [rax]
|
||||
|
||||
mov rax, [rsp+16]
|
||||
and rax, RANDOMX_CACHE_MASK
|
||||
shl rax, 6
|
||||
add rax, rdi
|
||||
mov [rsp+16], rax
|
||||
prefetchnta byte ptr [rax]
|
||||
|
||||
mov rax, [rsp+24]
|
||||
and rax, RANDOMX_CACHE_MASK
|
||||
shl rax, 6
|
||||
add rax, rdi
|
||||
mov [rsp+24], rax
|
||||
prefetchnta byte ptr [rax]
|
|
@ -1,5 +1,7 @@
|
|||
/*
|
||||
Copyright (c) 2018-2019, tevador <tevador@gmail.com>
|
||||
Copyright (c) 2018-2020, tevador <tevador@gmail.com>
|
||||
Copyright (c) 2019-2020, SChernykh <https://github.com/SChernykh>
|
||||
Copyright (c) 2019-2020, XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -59,10 +61,11 @@ namespace randomx {
|
|||
|
||||
template<class Allocator>
|
||||
void deallocCache(randomx_cache* cache) {
|
||||
if (cache->memory != nullptr)
|
||||
if (cache->memory != nullptr) {
|
||||
Allocator::freeMemory(cache->memory, RANDOMX_CACHE_MAX_SIZE);
|
||||
if (cache->jit != nullptr)
|
||||
delete cache->jit;
|
||||
}
|
||||
|
||||
delete cache->jit;
|
||||
}
|
||||
|
||||
template void deallocCache<DefaultAllocator>(randomx_cache* cache);
|
||||
|
@ -77,16 +80,16 @@ namespace randomx {
|
|||
context.pwdlen = (uint32_t)keySize;
|
||||
context.salt = CONST_CAST(uint8_t *)RandomX_CurrentConfig.ArgonSalt;
|
||||
context.saltlen = (uint32_t)strlen(RandomX_CurrentConfig.ArgonSalt);
|
||||
context.secret = NULL;
|
||||
context.secret = nullptr;
|
||||
context.secretlen = 0;
|
||||
context.ad = NULL;
|
||||
context.ad = nullptr;
|
||||
context.adlen = 0;
|
||||
context.t_cost = RandomX_CurrentConfig.ArgonIterations;
|
||||
context.m_cost = RandomX_CurrentConfig.ArgonMemory;
|
||||
context.lanes = RandomX_CurrentConfig.ArgonLanes;
|
||||
context.threads = 1;
|
||||
context.allocate_cbk = NULL;
|
||||
context.free_cbk = NULL;
|
||||
context.allocate_cbk = nullptr;
|
||||
context.free_cbk = nullptr;
|
||||
context.flags = ARGON2_DEFAULT_FLAGS;
|
||||
context.version = ARGON2_VERSION_NUMBER;
|
||||
|
||||
|
@ -100,8 +103,18 @@ namespace randomx {
|
|||
|
||||
void initCacheCompile(randomx_cache* cache, const void* key, size_t keySize) {
|
||||
initCache(cache, key, keySize);
|
||||
|
||||
# ifdef XMRIG_SECURE_JIT
|
||||
cache->jit->enableWriting();
|
||||
# endif
|
||||
|
||||
cache->jit->generateSuperscalarHash(cache->programs);
|
||||
cache->jit->generateDatasetInitCode();
|
||||
cache->datasetInit = cache->jit->getDatasetInitFunc();
|
||||
|
||||
# ifdef XMRIG_SECURE_JIT
|
||||
cache->jit->enableExecution();
|
||||
# endif
|
||||
}
|
||||
|
||||
constexpr uint64_t superscalarMul0 = 6364136223846793005ULL;
|
||||
|
|
|
@ -48,7 +48,7 @@ struct randomx_cache {
|
|||
randomx::DatasetInitFunc* datasetInit;
|
||||
randomx::SuperscalarProgram programs[RANDOMX_CACHE_MAX_ACCESSES];
|
||||
|
||||
bool isInitialized() {
|
||||
bool isInitialized() const {
|
||||
return programs[0].getSize() != 0;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
Copyright (c) 2018-2019, tevador <tevador@gmail.com>
|
||||
Copyright (c) 2019, SChernykh <https://github.com/SChernykh>
|
||||
Copyright (c) 2018-2020, tevador <tevador@gmail.com>
|
||||
Copyright (c) 2019-2020, SChernykh <https://github.com/SChernykh>
|
||||
Copyright (c) 2019-2020, XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -28,18 +29,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
*/
|
||||
|
||||
#include "crypto/randomx/jit_compiler_a64.hpp"
|
||||
#include "crypto/randomx/superscalar.hpp"
|
||||
#include "crypto/common/VirtualMemory.h"
|
||||
#include "crypto/randomx/program.hpp"
|
||||
#include "crypto/randomx/reciprocal.h"
|
||||
#include "crypto/randomx/superscalar.hpp"
|
||||
#include "crypto/randomx/virtual_memory.hpp"
|
||||
|
||||
static bool hugePagesJIT = false;
|
||||
static int optimizedDatasetInit = -1;
|
||||
|
||||
void randomx_set_huge_pages_jit(bool hugePages)
|
||||
{
|
||||
hugePagesJIT = hugePages;
|
||||
}
|
||||
|
||||
void randomx_set_optimized_dataset_init(int value)
|
||||
{
|
||||
optimizedDatasetInit = value;
|
||||
}
|
||||
|
||||
namespace ARMV8A {
|
||||
|
||||
constexpr uint32_t B = 0x14000000;
|
||||
|
@ -96,37 +104,28 @@ static size_t CalcDatasetItemSize()
|
|||
|
||||
constexpr uint32_t IntRegMap[8] = { 4, 5, 6, 7, 12, 13, 14, 15 };
|
||||
|
||||
JitCompilerA64::JitCompilerA64(bool hugePagesEnable)
|
||||
: code((uint8_t*) allocExecutableMemory(CodeSize + CalcDatasetItemSize(), hugePagesJIT && hugePagesEnable))
|
||||
, literalPos(ImulRcpLiteralsEnd)
|
||||
, num32bitLiterals(0)
|
||||
JitCompilerA64::JitCompilerA64(bool hugePagesEnable, bool) :
|
||||
hugePages(hugePagesJIT && hugePagesEnable),
|
||||
literalPos(ImulRcpLiteralsEnd)
|
||||
{
|
||||
memset(reg_changed_offset, 0, sizeof(reg_changed_offset));
|
||||
memcpy(code, (void*) randomx_program_aarch64, CodeSize);
|
||||
}
|
||||
|
||||
JitCompilerA64::~JitCompilerA64()
|
||||
{
|
||||
freePagedMemory(code, CodeSize + CalcDatasetItemSize());
|
||||
}
|
||||
|
||||
#if defined(ios_HOST_OS) || defined (darwin_HOST_OS)
|
||||
void sys_icache_invalidate(void *start, size_t len);
|
||||
#endif
|
||||
|
||||
static void clear_code_cache(char* p1, char* p2)
|
||||
{
|
||||
# if defined(ios_HOST_OS) || defined (darwin_HOST_OS)
|
||||
sys_icache_invalidate(p1, static_cast<size_t>(p2 - p1));
|
||||
# elif defined (HAVE_BUILTIN_CLEAR_CACHE) || defined (__GNUC__)
|
||||
__builtin___clear_cache(p1, p2);
|
||||
# else
|
||||
# error "No clear code cache function found"
|
||||
# endif
|
||||
freePagedMemory(code, allocatedSize);
|
||||
}
|
||||
|
||||
void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& config, uint32_t)
|
||||
{
|
||||
if (!allocatedSize) {
|
||||
allocate(CodeSize);
|
||||
}
|
||||
#ifdef XMRIG_SECURE_JIT
|
||||
else {
|
||||
enableWriting();
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t codePos = MainLoopBegin + 4;
|
||||
|
||||
// and w16, w10, ScratchpadL3Mask64
|
||||
|
@ -171,11 +170,22 @@ void JitCompilerA64::generateProgram(Program& program, ProgramConfiguration& con
|
|||
codePos = ((uint8_t*)randomx_program_aarch64_update_spMix1) - ((uint8_t*)randomx_program_aarch64);
|
||||
emit32(ARMV8A::EOR | 10 | (IntRegMap[config.readReg0] << 5) | (IntRegMap[config.readReg1] << 16), code, codePos);
|
||||
|
||||
clear_code_cache(reinterpret_cast<char*>(code + MainLoopBegin), reinterpret_cast<char*>(code + codePos));
|
||||
# ifndef XMRIG_OS_APPLE
|
||||
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), reinterpret_cast<char*>(code + codePos));
|
||||
# endif
|
||||
}
|
||||
|
||||
void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration& config, uint32_t datasetOffset)
|
||||
{
|
||||
if (!allocatedSize) {
|
||||
allocate(CodeSize);
|
||||
}
|
||||
#ifdef XMRIG_SECURE_JIT
|
||||
else {
|
||||
enableWriting();
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t codePos = MainLoopBegin + 4;
|
||||
|
||||
// and w16, w10, ScratchpadL3Mask64
|
||||
|
@ -226,12 +236,23 @@ void JitCompilerA64::generateProgramLight(Program& program, ProgramConfiguration
|
|||
emit32(ARMV8A::ADD_IMM_LO | 2 | (2 << 5) | (imm_lo << 10), code, codePos);
|
||||
emit32(ARMV8A::ADD_IMM_HI | 2 | (2 << 5) | (imm_hi << 10), code, codePos);
|
||||
|
||||
clear_code_cache(reinterpret_cast<char*>(code + MainLoopBegin), reinterpret_cast<char*>(code + codePos));
|
||||
# ifndef XMRIG_OS_APPLE
|
||||
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + MainLoopBegin), reinterpret_cast<char*>(code + codePos));
|
||||
# endif
|
||||
}
|
||||
|
||||
template<size_t N>
|
||||
void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[N])
|
||||
{
|
||||
if (!allocatedSize) {
|
||||
allocate(CodeSize + CalcDatasetItemSize());
|
||||
}
|
||||
#ifdef XMRIG_SECURE_JIT
|
||||
else {
|
||||
enableWriting();
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t codePos = CodeSize;
|
||||
|
||||
uint8_t* p1 = (uint8_t*)randomx_calc_dataset_item_aarch64;
|
||||
|
@ -342,13 +363,19 @@ void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[N])
|
|||
memcpy(code + codePos, p1, p2 - p1);
|
||||
codePos += p2 - p1;
|
||||
|
||||
clear_code_cache(reinterpret_cast<char*>(code + CodeSize), reinterpret_cast<char*>(code + codePos));
|
||||
# ifndef XMRIG_OS_APPLE
|
||||
xmrig::VirtualMemory::flushInstructionCache(reinterpret_cast<char*>(code + CodeSize), reinterpret_cast<char*>(code + codePos));
|
||||
# endif
|
||||
}
|
||||
|
||||
template void JitCompilerA64::generateSuperscalarHash(SuperscalarProgram(&programs)[RANDOMX_CACHE_MAX_ACCESSES]);
|
||||
|
||||
DatasetInitFunc* JitCompilerA64::getDatasetInitFunc()
|
||||
DatasetInitFunc* JitCompilerA64::getDatasetInitFunc() const
|
||||
{
|
||||
# ifdef XMRIG_SECURE_JIT
|
||||
enableExecution();
|
||||
# endif
|
||||
|
||||
return (DatasetInitFunc*)(code + (((uint8_t*)randomx_init_dataset_aarch64) - ((uint8_t*)randomx_program_aarch64)));
|
||||
}
|
||||
|
||||
|
@ -357,6 +384,26 @@ size_t JitCompilerA64::getCodeSize()
|
|||
return CodeSize;
|
||||
}
|
||||
|
||||
void JitCompilerA64::enableWriting() const
|
||||
{
|
||||
xmrig::VirtualMemory::protectRW(code, allocatedSize);
|
||||
}
|
||||
|
||||
void JitCompilerA64::enableExecution() const
|
||||
{
|
||||
xmrig::VirtualMemory::protectRX(code, allocatedSize);
|
||||
}
|
||||
|
||||
|
||||
void JitCompilerA64::allocate(size_t size)
|
||||
{
|
||||
allocatedSize = size;
|
||||
code = static_cast<uint8_t*>(allocExecutableMemory(allocatedSize, hugePages));
|
||||
|
||||
memcpy(code, reinterpret_cast<const void *>(randomx_program_aarch64), CodeSize);
|
||||
}
|
||||
|
||||
|
||||
void JitCompilerA64::emitMovImmediate(uint32_t dst, uint32_t imm, uint8_t* code, uint32_t& codePos)
|
||||
{
|
||||
uint32_t k = codePos;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
Copyright (c) 2018-2019, tevador <tevador@gmail.com>
|
||||
Copyright (c) 2019, SChernykh <https://github.com/SChernykh>
|
||||
Copyright (c) 2018-2020, tevador <tevador@gmail.com>
|
||||
Copyright (c) 2019-2020, SChernykh <https://github.com/SChernykh>
|
||||
Copyright (c) 2019-2020, XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -46,7 +47,7 @@ namespace randomx {
|
|||
|
||||
class JitCompilerA64 {
|
||||
public:
|
||||
explicit JitCompilerA64(bool hugePagesEnable);
|
||||
explicit JitCompilerA64(bool hugePagesEnable, bool optimizedInitDatasetEnable);
|
||||
~JitCompilerA64();
|
||||
|
||||
void prepare() {}
|
||||
|
@ -58,16 +59,32 @@ namespace randomx {
|
|||
|
||||
void generateDatasetInitCode() {}
|
||||
|
||||
ProgramFunc* getProgramFunc() { return reinterpret_cast<ProgramFunc*>(code); }
|
||||
DatasetInitFunc* getDatasetInitFunc();
|
||||
inline ProgramFunc *getProgramFunc() const {
|
||||
# ifdef XMRIG_SECURE_JIT
|
||||
enableExecution();
|
||||
# endif
|
||||
|
||||
return reinterpret_cast<ProgramFunc*>(code);
|
||||
}
|
||||
|
||||
DatasetInitFunc* getDatasetInitFunc() const;
|
||||
uint8_t* getCode() { return code; }
|
||||
size_t getCodeSize();
|
||||
|
||||
void enableWriting() const;
|
||||
void enableExecution() const;
|
||||
|
||||
static InstructionGeneratorA64 engine[256];
|
||||
uint32_t reg_changed_offset[8];
|
||||
uint8_t* code;
|
||||
|
||||
private:
|
||||
const bool hugePages;
|
||||
uint32_t reg_changed_offset[8]{};
|
||||
uint8_t* code = nullptr;
|
||||
uint32_t literalPos;
|
||||
uint32_t num32bitLiterals;
|
||||
uint32_t num32bitLiterals = 0;
|
||||
size_t allocatedSize = 0;
|
||||
|
||||
void allocate(size_t size);
|
||||
|
||||
static void emit32(uint32_t val, uint8_t* code, uint32_t& codePos)
|
||||
{
|
||||
|
@ -90,6 +107,7 @@ namespace randomx {
|
|||
template<uint32_t tmp_reg_fp>
|
||||
void emitMemLoadFP(uint32_t src, Instruction& instr, uint8_t* code, uint32_t& codePos);
|
||||
|
||||
public:
|
||||
void h_IADD_RS(Instruction&, uint32_t&);
|
||||
void h_IADD_M(Instruction&, uint32_t&);
|
||||
void h_ISUB_R(Instruction&, uint32_t&);
|
||||
|
|
|
@ -35,3 +35,6 @@ void randomx_set_huge_pages_jit(bool)
|
|||
{
|
||||
}
|
||||
|
||||
void randomx_set_optimized_dataset_init(int)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/*
|
||||
Copyright (c) 2018-2019, tevador <tevador@gmail.com>
|
||||
Copyright (c) 2018-2020, tevador <tevador@gmail.com>
|
||||
Copyright (c) 2019-2020, SChernykh <https://github.com/SChernykh>
|
||||
Copyright (c) 2019-2020, XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -41,7 +43,7 @@ namespace randomx {
|
|||
|
||||
class JitCompilerFallback {
|
||||
public:
|
||||
explicit JitCompilerFallback(bool) {
|
||||
explicit JitCompilerFallback(bool, bool) {
|
||||
throw std::runtime_error("JIT compilation is not supported on this platform");
|
||||
}
|
||||
void prepare() {}
|
||||
|
@ -70,5 +72,7 @@ namespace randomx {
|
|||
size_t getCodeSize() {
|
||||
return 0;
|
||||
}
|
||||
void enableWriting() {}
|
||||
void enableExecution() {}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/*
|
||||
Copyright (c) 2018-2019, tevador <tevador@gmail.com>
|
||||
Copyright (c) 2018-2020, tevador <tevador@gmail.com>
|
||||
Copyright (c) 2019-2020, SChernykh <https://github.com/SChernykh>
|
||||
Copyright (c) 2019-2020, XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -30,14 +32,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <cstring>
|
||||
#include <climits>
|
||||
#include <atomic>
|
||||
|
||||
#include "crypto/randomx/jit_compiler_x86.hpp"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "crypto/common/VirtualMemory.h"
|
||||
#include "crypto/randomx/jit_compiler_x86_static.hpp"
|
||||
#include "crypto/randomx/superscalar.hpp"
|
||||
#include "crypto/randomx/program.hpp"
|
||||
#include "crypto/randomx/reciprocal.h"
|
||||
#include "crypto/randomx/superscalar.hpp"
|
||||
#include "crypto/randomx/virtual_memory.hpp"
|
||||
#include "base/tools/Profiler.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "crypto/rx/Profiler.h"
|
||||
|
||||
#ifdef XMRIG_FIX_RYZEN
|
||||
# include "crypto/rx/Rx.h"
|
||||
|
@ -45,17 +49,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
#else
|
||||
# include <cpuid.h>
|
||||
#endif
|
||||
|
||||
static bool hugePagesJIT = false;
|
||||
static int optimizedDatasetInit = -1;
|
||||
|
||||
void randomx_set_huge_pages_jit(bool hugePages)
|
||||
{
|
||||
hugePagesJIT = hugePages;
|
||||
}
|
||||
|
||||
void randomx_set_optimized_dataset_init(int value)
|
||||
{
|
||||
optimizedDatasetInit = value;
|
||||
}
|
||||
|
||||
namespace randomx {
|
||||
/*
|
||||
|
||||
|
@ -112,6 +120,11 @@ namespace randomx {
|
|||
#define codeReadDatasetLightSshInit ADDR(randomx_program_read_dataset_sshash_init)
|
||||
#define codeReadDatasetLightSshFin ADDR(randomx_program_read_dataset_sshash_fin)
|
||||
#define codeDatasetInit ADDR(randomx_dataset_init)
|
||||
#define codeDatasetInitAVX2_prologue ADDR(randomx_dataset_init_avx2_prologue)
|
||||
#define codeDatasetInitAVX2_loop_end ADDR(randomx_dataset_init_avx2_loop_end)
|
||||
#define codeDatasetInitAVX2_loop_epilogue ADDR(randomx_dataset_init_avx2_epilogue)
|
||||
#define codeDatasetInitAVX2_ssh_load ADDR(randomx_dataset_init_avx2_ssh_load)
|
||||
#define codeDatasetInitAVX2_ssh_prefetch ADDR(randomx_dataset_init_avx2_ssh_prefetch)
|
||||
#define codeLoopStore ADDR(randomx_program_loop_store)
|
||||
#define codeLoopEnd ADDR(randomx_program_loop_end)
|
||||
#define codeEpilogue ADDR(randomx_program_epilogue)
|
||||
|
@ -128,7 +141,12 @@ namespace randomx {
|
|||
#define readDatasetLightInitSize (codeReadDatasetLightSshFin - codeReadDatasetLightSshInit)
|
||||
#define readDatasetLightFinSize (codeLoopStore - codeReadDatasetLightSshFin)
|
||||
#define loopStoreSize (codeLoopEnd - codeLoopStore)
|
||||
#define datasetInitSize (codeEpilogue - codeDatasetInit)
|
||||
#define datasetInitSize (codeDatasetInitAVX2_prologue - codeDatasetInit)
|
||||
#define datasetInitAVX2_prologue_size (codeDatasetInitAVX2_loop_end - codeDatasetInitAVX2_prologue)
|
||||
#define datasetInitAVX2_loop_end_size (codeDatasetInitAVX2_loop_epilogue - codeDatasetInitAVX2_loop_end)
|
||||
#define datasetInitAVX2_epilogue_size (codeDatasetInitAVX2_ssh_load - codeDatasetInitAVX2_loop_epilogue)
|
||||
#define datasetInitAVX2_ssh_load_size (codeDatasetInitAVX2_ssh_prefetch - codeDatasetInitAVX2_ssh_load)
|
||||
#define datasetInitAVX2_ssh_prefetch_size (codeEpilogue - codeDatasetInitAVX2_ssh_prefetch)
|
||||
#define epilogueSize (codeShhLoad - codeEpilogue)
|
||||
#define codeSshLoadSize (codeShhPrefetch - codeShhLoad)
|
||||
#define codeSshPrefetchSize (codeShhEnd - codeShhPrefetch)
|
||||
|
@ -166,20 +184,27 @@ namespace randomx {
|
|||
{0x0F, 0x1F, 0x44, 0x00, 0x00, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E},
|
||||
};
|
||||
|
||||
static inline uint8_t* alignToPage(uint8_t* p, size_t pageSize) {
|
||||
size_t k = (size_t) p;
|
||||
k -= k % pageSize;
|
||||
return (uint8_t*) k;
|
||||
}
|
||||
|
||||
size_t JitCompilerX86::getCodeSize() {
|
||||
return codePos < prologueSize ? 0 : codePos - prologueSize;
|
||||
}
|
||||
|
||||
static inline void cpuid(uint32_t level, int32_t output[4])
|
||||
{
|
||||
memset(output, 0, sizeof(int32_t) * 4);
|
||||
void JitCompilerX86::enableWriting() const {
|
||||
uint8_t* p1 = alignToPage(code, 4096);
|
||||
uint8_t* p2 = code + CodeSize;
|
||||
xmrig::VirtualMemory::protectRW(p1, p2 - p1);
|
||||
}
|
||||
|
||||
# ifdef _MSC_VER
|
||||
__cpuid(output, static_cast<int>(level));
|
||||
# else
|
||||
__cpuid_count(level, 0, output[0], output[1], output[2], output[3]);
|
||||
# endif
|
||||
}
|
||||
void JitCompilerX86::enableExecution() const {
|
||||
uint8_t* p1 = alignToPage(code, 4096);
|
||||
uint8_t* p2 = code + CodeSize;
|
||||
xmrig::VirtualMemory::protectRX(p1, p2 - p1);
|
||||
}
|
||||
|
||||
# ifdef _MSC_VER
|
||||
static FORCE_INLINE uint32_t rotl32(uint32_t a, int shift) { return _rotl(a, shift); }
|
||||
|
@ -190,17 +215,68 @@ namespace randomx {
|
|||
static std::atomic<size_t> codeOffset;
|
||||
constexpr size_t codeOffsetIncrement = 59 * 64;
|
||||
|
||||
JitCompilerX86::JitCompilerX86(bool hugePagesEnable) {
|
||||
JitCompilerX86::JitCompilerX86(bool hugePagesEnable, bool optimizedInitDatasetEnable) {
|
||||
BranchesWithin32B = xmrig::Cpu::info()->jccErratum();
|
||||
|
||||
int32_t info[4];
|
||||
cpuid(1, info);
|
||||
hasAVX = ((info[2] & (1 << 27)) != 0) && ((info[2] & (1 << 28)) != 0);
|
||||
hasAVX = xmrig::Cpu::info()->hasAVX();
|
||||
hasAVX2 = xmrig::Cpu::info()->hasAVX2();
|
||||
|
||||
cpuid(0x80000001, info);
|
||||
hasXOP = ((info[2] & (1 << 11)) != 0);
|
||||
// Disable by default
|
||||
initDatasetAVX2 = false;
|
||||
|
||||
allocatedCode = (uint8_t*)allocExecutableMemory(CodeSize * 2, hugePagesJIT && hugePagesEnable);
|
||||
if (optimizedInitDatasetEnable) {
|
||||
// Dataset init using AVX2:
|
||||
// -1 = Auto detect
|
||||
// 0 = Always disabled
|
||||
// +1 = Always enabled
|
||||
if (optimizedDatasetInit > 0) {
|
||||
initDatasetAVX2 = true;
|
||||
}
|
||||
else if (optimizedDatasetInit < 0) {
|
||||
xmrig::ICpuInfo::Vendor vendor = xmrig::Cpu::info()->vendor();
|
||||
xmrig::ICpuInfo::Arch arch = xmrig::Cpu::info()->arch();
|
||||
|
||||
if (vendor == xmrig::ICpuInfo::VENDOR_INTEL) {
|
||||
// AVX2 init is faster on Intel CPUs without HT
|
||||
initDatasetAVX2 = (xmrig::Cpu::info()->cores() == xmrig::Cpu::info()->threads());
|
||||
}
|
||||
else if (vendor == xmrig::ICpuInfo::VENDOR_AMD) {
|
||||
switch (arch) {
|
||||
case xmrig::ICpuInfo::ARCH_ZEN:
|
||||
case xmrig::ICpuInfo::ARCH_ZEN_PLUS:
|
||||
default:
|
||||
// AVX2 init is slower on Zen/Zen+
|
||||
// Also disable it for other unknown architectures
|
||||
initDatasetAVX2 = false;
|
||||
break;
|
||||
case xmrig::ICpuInfo::ARCH_ZEN2:
|
||||
// AVX2 init is faster on Zen2 without SMT (mobile CPUs)
|
||||
initDatasetAVX2 = (xmrig::Cpu::info()->cores() == xmrig::Cpu::info()->threads());
|
||||
break;
|
||||
case xmrig::ICpuInfo::ARCH_ZEN3:
|
||||
// AVX2 init is faster on Zen3
|
||||
initDatasetAVX2 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sorry, low-end Intel CPUs
|
||||
if (!hasAVX2) {
|
||||
initDatasetAVX2 = false;
|
||||
}
|
||||
|
||||
hasXOP = xmrig::Cpu::info()->hasXOP();
|
||||
|
||||
allocatedSize = initDatasetAVX2 ? (CodeSize * 4) : (CodeSize * 2);
|
||||
allocatedCode = static_cast<uint8_t*>(allocExecutableMemory(allocatedSize,
|
||||
# ifdef XMRIG_SECURE_JIT
|
||||
false
|
||||
# else
|
||||
hugePagesJIT && hugePagesEnable
|
||||
# endif
|
||||
));
|
||||
|
||||
// Shift code base address to improve caching - all threads will use different L2/L3 cache sets
|
||||
code = allocatedCode + (codeOffset.fetch_add(codeOffsetIncrement) % CodeSize);
|
||||
|
@ -224,7 +300,7 @@ namespace randomx {
|
|||
|
||||
JitCompilerX86::~JitCompilerX86() {
|
||||
codeOffset.fetch_sub(codeOffsetIncrement);
|
||||
freePagedMemory(allocatedCode, CodeSize);
|
||||
freePagedMemory(allocatedCode, allocatedSize);
|
||||
}
|
||||
|
||||
void JitCompilerX86::prepare() {
|
||||
|
@ -237,6 +313,10 @@ namespace randomx {
|
|||
void JitCompilerX86::generateProgram(Program& prog, ProgramConfiguration& pcfg, uint32_t flags) {
|
||||
PROFILE_SCOPE(RandomX_JIT_compile);
|
||||
|
||||
# ifdef XMRIG_SECURE_JIT
|
||||
enableWriting();
|
||||
# endif
|
||||
|
||||
vm_flags = flags;
|
||||
|
||||
generateProgramPrologue(prog, pcfg);
|
||||
|
@ -271,14 +351,49 @@ namespace randomx {
|
|||
|
||||
template<size_t N>
|
||||
void JitCompilerX86::generateSuperscalarHash(SuperscalarProgram(&programs)[N]) {
|
||||
uint8_t* p = code;
|
||||
if (initDatasetAVX2) {
|
||||
codePos = 0;
|
||||
emit(codeDatasetInitAVX2_prologue, datasetInitAVX2_prologue_size, code, codePos);
|
||||
|
||||
for (unsigned j = 0; j < RandomX_CurrentConfig.CacheAccesses; ++j) {
|
||||
SuperscalarProgram& prog = programs[j];
|
||||
uint32_t pos = codePos;
|
||||
for (uint32_t i = 0, n = prog.getSize(); i < n; ++i) {
|
||||
generateSuperscalarCode<true>(prog(i), p, pos);
|
||||
}
|
||||
codePos = pos;
|
||||
emit(codeShhLoad, codeSshLoadSize, code, codePos);
|
||||
emit(codeDatasetInitAVX2_ssh_load, datasetInitAVX2_ssh_load_size, code, codePos);
|
||||
if (j < RandomX_CurrentConfig.CacheAccesses - 1) {
|
||||
*(uint32_t*)(code + codePos) = 0xd88b49 + (static_cast<uint32_t>(prog.getAddressRegister()) << 16);
|
||||
codePos += 3;
|
||||
emit(RandomX_CurrentConfig.codeShhPrefetchTweaked, codeSshPrefetchSize, code, codePos);
|
||||
uint8_t* p = code + codePos;
|
||||
emit(codeDatasetInitAVX2_ssh_prefetch, datasetInitAVX2_ssh_prefetch_size, code, codePos);
|
||||
p[3] += prog.getAddressRegister() << 3;
|
||||
}
|
||||
}
|
||||
|
||||
emit(codeDatasetInitAVX2_loop_end, datasetInitAVX2_loop_end_size, code, codePos);
|
||||
|
||||
// Number of bytes from the start of randomx_dataset_init_avx2_prologue to loop_begin label
|
||||
constexpr int32_t prologue_size = 320;
|
||||
*(int32_t*)(code + codePos - 4) = prologue_size - codePos;
|
||||
|
||||
emit(codeDatasetInitAVX2_loop_epilogue, datasetInitAVX2_epilogue_size, code, codePos);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(code + superScalarHashOffset, codeShhInit, codeSshInitSize);
|
||||
codePos = superScalarHashOffset + codeSshInitSize;
|
||||
for (unsigned j = 0; j < RandomX_CurrentConfig.CacheAccesses; ++j) {
|
||||
SuperscalarProgram& prog = programs[j];
|
||||
for (unsigned i = 0; i < prog.getSize(); ++i) {
|
||||
Instruction& instr = prog(i);
|
||||
generateSuperscalarCode(instr);
|
||||
uint32_t pos = codePos;
|
||||
for (uint32_t i = 0, n = prog.getSize(); i < n; ++i) {
|
||||
generateSuperscalarCode<false>(prog(i), p, pos);
|
||||
}
|
||||
codePos = pos;
|
||||
emit(codeShhLoad, codeSshLoadSize, code, codePos);
|
||||
if (j < RandomX_CurrentConfig.CacheAccesses - 1) {
|
||||
*(uint32_t*)(code + codePos) = 0xd88b49 + (static_cast<uint32_t>(prog.getAddressRegister()) << 16);
|
||||
|
@ -293,7 +408,10 @@ namespace randomx {
|
|||
void JitCompilerX86::generateSuperscalarHash(SuperscalarProgram(&programs)[RANDOMX_CACHE_MAX_ACCESSES]);
|
||||
|
||||
void JitCompilerX86::generateDatasetInitCode() {
|
||||
memcpy(code, codeDatasetInit, datasetInitSize);
|
||||
// AVX2 code is generated in generateSuperscalarHash()
|
||||
if (!initDatasetAVX2) {
|
||||
memcpy(code, codeDatasetInit, datasetInitSize);
|
||||
}
|
||||
}
|
||||
|
||||
void JitCompilerX86::generateProgramPrologue(Program& prog, ProgramConfiguration& pcfg) {
|
||||
|
@ -372,101 +490,243 @@ namespace randomx {
|
|||
emit32(epilogueOffset - codePos - 4, code, codePos);
|
||||
}
|
||||
|
||||
void JitCompilerX86::generateSuperscalarCode(Instruction& instr) {
|
||||
static constexpr uint8_t REX_SUB_RR[] = { 0x4d, 0x2b };
|
||||
static constexpr uint8_t REX_MOV_RR64[] = { 0x49, 0x8b };
|
||||
static constexpr uint8_t REX_MOV_R64R[] = { 0x4c, 0x8b };
|
||||
static constexpr uint8_t REX_IMUL_RR[] = { 0x4d, 0x0f, 0xaf };
|
||||
static constexpr uint8_t REX_IMUL_RM[] = { 0x4c, 0x0f, 0xaf };
|
||||
static constexpr uint8_t REX_MUL_R[] = { 0x49, 0xf7 };
|
||||
static constexpr uint8_t REX_81[] = { 0x49, 0x81 };
|
||||
static constexpr uint8_t MOV_RAX_I[] = { 0x48, 0xb8 };
|
||||
static constexpr uint8_t REX_LEA[] = { 0x4f, 0x8d };
|
||||
static constexpr uint8_t REX_XOR_RR[] = { 0x4D, 0x33 };
|
||||
static constexpr uint8_t REX_XOR_RI[] = { 0x49, 0x81 };
|
||||
static constexpr uint8_t REX_ROT_I8[] = { 0x49, 0xc1 };
|
||||
|
||||
template<bool AVX2>
|
||||
FORCE_INLINE void JitCompilerX86::generateSuperscalarCode(Instruction& instr, uint8_t* code, uint32_t& codePos) {
|
||||
switch ((SuperscalarInstructionType)instr.opcode)
|
||||
{
|
||||
case randomx::SuperscalarInstructionType::ISUB_R:
|
||||
emit(REX_SUB_RR, code, codePos);
|
||||
emitByte(0xc0 + 8 * instr.dst + instr.src, code, codePos);
|
||||
*(uint32_t*)(code + codePos) = 0x00C02B4DUL + (instr.dst << 19) + (instr.src << 16);
|
||||
codePos += 3;
|
||||
if (AVX2) {
|
||||
emit32(0xC0FBFDC5UL + (instr.src << 24) + (instr.dst << 27) - (instr.dst << 11), code, codePos);
|
||||
}
|
||||
break;
|
||||
case randomx::SuperscalarInstructionType::IXOR_R:
|
||||
emit(REX_XOR_RR, code, codePos);
|
||||
emitByte(0xc0 + 8 * instr.dst + instr.src, code, codePos);
|
||||
*(uint32_t*)(code + codePos) = 0x00C0334DUL + (instr.dst << 19) + (instr.src << 16);
|
||||
codePos += 3;
|
||||
if (AVX2) {
|
||||
emit32(0xC0EFFDC5UL + (instr.src << 24) + (instr.dst << 27) - (instr.dst << 11), code, codePos);
|
||||
}
|
||||
break;
|
||||
case randomx::SuperscalarInstructionType::IADD_RS:
|
||||
emit(REX_LEA, code, codePos);
|
||||
emitByte(0x04 + 8 * instr.dst, code, codePos);
|
||||
genSIB(instr.getModShift(), instr.src, instr.dst, code, codePos);
|
||||
emit32(0x00048D4F + (instr.dst << 19) + (genSIB(instr.getModShift(), instr.src, instr.dst) << 24), code, codePos);
|
||||
if (AVX2) {
|
||||
if (instr.getModShift()) {
|
||||
static const uint8_t t[] = { 0xC5, 0xBD, 0x73, 0xF0, 0x00, 0xC5, 0xBD, 0xD4, 0xC0 };
|
||||
uint8_t* p = code + codePos;
|
||||
emit(t, code, codePos);
|
||||
p[3] += instr.src;
|
||||
p[4] = instr.getModShift();
|
||||
p[8] += instr.dst * 9;
|
||||
}
|
||||
else {
|
||||
emit32(0xC0D4FDC5UL + (instr.src << 24) + (instr.dst << 27) - (instr.dst << 11), code, codePos);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case randomx::SuperscalarInstructionType::IMUL_R:
|
||||
emit(REX_IMUL_RR, code, codePos);
|
||||
emitByte(0xc0 + 8 * instr.dst + instr.src, code, codePos);
|
||||
emit32(0xC0AF0F4DUL + (instr.dst << 27) + (instr.src << 24), code, codePos);
|
||||
if (AVX2) {
|
||||
static const uint8_t t[] = {
|
||||
0xC5, 0xBD, 0x73, 0xD0, 0x20,
|
||||
0xC5, 0xB5, 0x73, 0xD0, 0x20,
|
||||
0xC5, 0x7D, 0xF4, 0xD0,
|
||||
0xC5, 0x35, 0xF4, 0xD8,
|
||||
0xC5, 0xBD, 0xF4, 0xC0,
|
||||
0xC4, 0xC1, 0x25, 0x73, 0xF3, 0x20,
|
||||
0xC5, 0xFD, 0x73, 0xF0, 0x20,
|
||||
0xC4, 0x41, 0x2D, 0xD4, 0xD3,
|
||||
0xC5, 0xAD, 0xD4, 0xC0
|
||||
};
|
||||
uint8_t* p = code + codePos;
|
||||
emit(t, code, codePos);
|
||||
p[3] += instr.dst;
|
||||
p[8] += instr.src;
|
||||
p[11] -= instr.dst * 8;
|
||||
p[13] += instr.src;
|
||||
p[17] += instr.dst;
|
||||
p[21] += instr.dst * 8 + instr.src;
|
||||
p[29] -= instr.dst * 8;
|
||||
p[31] += instr.dst;
|
||||
p[41] += instr.dst * 9;
|
||||
}
|
||||
break;
|
||||
case randomx::SuperscalarInstructionType::IROR_C:
|
||||
emit(REX_ROT_I8, code, codePos);
|
||||
emitByte(0xc8 + instr.dst, code, codePos);
|
||||
emitByte(instr.getImm32() & 63, code, codePos);
|
||||
{
|
||||
const uint32_t shift = instr.getImm32() & 63;
|
||||
emit32(0x00C8C149UL + (instr.dst << 16) + (shift << 24), code, codePos);
|
||||
if (AVX2) {
|
||||
static const uint8_t t[] = { 0xC5, 0xBD, 0x73, 0xD0, 0x00, 0xC5, 0xB5, 0x73, 0xF0, 0x00, 0xC4, 0xC1, 0x3D, 0xEB, 0xC1 };
|
||||
uint8_t* p = code + codePos;
|
||||
emit(t, code, codePos);
|
||||
p[3] += instr.dst;
|
||||
p[4] = shift;
|
||||
p[8] += instr.dst;
|
||||
p[9] = 64 - shift;
|
||||
p[14] += instr.dst * 8;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case randomx::SuperscalarInstructionType::IADD_C7:
|
||||
emit(REX_81, code, codePos);
|
||||
emitByte(0xc0 + instr.dst, code, codePos);
|
||||
emit32(instr.getImm32(), code, codePos);
|
||||
case randomx::SuperscalarInstructionType::IADD_C8:
|
||||
case randomx::SuperscalarInstructionType::IADD_C9:
|
||||
if (AVX2) {
|
||||
static const uint8_t t[] = { 0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x03, 0xC0, 0xC4, 0x62, 0x7D, 0x19, 0x05, 0xEC, 0xFF, 0xFF, 0xFF, 0xC4, 0xC1, 0x7D, 0xD4, 0xC0 };
|
||||
uint8_t* p = code + codePos;
|
||||
emit(t, code, codePos);
|
||||
*(uint64_t*)(p + 2) = signExtend2sCompl(instr.getImm32());
|
||||
p[12] += instr.dst * 8;
|
||||
p[24] -= instr.dst * 8;
|
||||
p[26] += instr.dst * 8;
|
||||
}
|
||||
else {
|
||||
*(uint32_t*)(code + codePos) = 0x00C08149UL + (instr.dst << 16);
|
||||
codePos += 3;
|
||||
emit32(instr.getImm32(), code, codePos);
|
||||
}
|
||||
break;
|
||||
case randomx::SuperscalarInstructionType::IXOR_C7:
|
||||
emit(REX_XOR_RI, code, codePos);
|
||||
emitByte(0xf0 + instr.dst, code, codePos);
|
||||
emit32(instr.getImm32(), code, codePos);
|
||||
break;
|
||||
case randomx::SuperscalarInstructionType::IADD_C8:
|
||||
emit(REX_81, code, codePos);
|
||||
emitByte(0xc0 + instr.dst, code, codePos);
|
||||
emit32(instr.getImm32(), code, codePos);
|
||||
break;
|
||||
case randomx::SuperscalarInstructionType::IXOR_C8:
|
||||
emit(REX_XOR_RI, code, codePos);
|
||||
emitByte(0xf0 + instr.dst, code, codePos);
|
||||
emit32(instr.getImm32(), code, codePos);
|
||||
break;
|
||||
case randomx::SuperscalarInstructionType::IADD_C9:
|
||||
emit(REX_81, code, codePos);
|
||||
emitByte(0xc0 + instr.dst, code, codePos);
|
||||
emit32(instr.getImm32(), code, codePos);
|
||||
break;
|
||||
case randomx::SuperscalarInstructionType::IXOR_C9:
|
||||
emit(REX_XOR_RI, code, codePos);
|
||||
emitByte(0xf0 + instr.dst, code, codePos);
|
||||
emit32(instr.getImm32(), code, codePos);
|
||||
if (AVX2) {
|
||||
static const uint8_t t[] = { 0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x33, 0xC0, 0xC4, 0x62, 0x7D, 0x19, 0x05, 0xEC, 0xFF, 0xFF, 0xFF, 0xC4, 0xC1, 0x7D, 0xEF, 0xC0 };
|
||||
uint8_t* p = code + codePos;
|
||||
emit(t, code, codePos);
|
||||
*(uint64_t*)(p + 2) = signExtend2sCompl(instr.getImm32());
|
||||
p[12] += instr.dst * 8;
|
||||
p[24] -= instr.dst * 8;
|
||||
p[26] += instr.dst * 8;
|
||||
}
|
||||
else {
|
||||
*(uint32_t*)(code + codePos) = 0x00F08149UL + (instr.dst << 16);
|
||||
codePos += 3;
|
||||
emit32(instr.getImm32(), code, codePos);
|
||||
}
|
||||
break;
|
||||
case randomx::SuperscalarInstructionType::IMULH_R:
|
||||
emit(REX_MOV_RR64, code, codePos);
|
||||
emitByte(0xc0 + instr.dst, code, codePos);
|
||||
emit(REX_MUL_R, code, codePos);
|
||||
emitByte(0xe0 + instr.src, code, codePos);
|
||||
emit(REX_MOV_R64R, code, codePos);
|
||||
emitByte(0xc2 + 8 * instr.dst, code, codePos);
|
||||
*(uint32_t*)(code + codePos) = 0x00C08B49UL + (instr.dst << 16);
|
||||
codePos += 3;
|
||||
*(uint32_t*)(code + codePos) = 0x00E0F749UL + (instr.src << 16);
|
||||
codePos += 3;
|
||||
*(uint32_t*)(code + codePos) = 0x00C28B4CUL + (instr.dst << 19);
|
||||
codePos += 3;
|
||||
if (AVX2) {
|
||||
static const uint8_t t[] = {
|
||||
0xC5, 0xBD, 0x73, 0xD0, 0x20,
|
||||
0xC5, 0xB5, 0x73, 0xD0, 0x20,
|
||||
0xC5, 0x7D, 0xF4, 0xD0,
|
||||
0xC5, 0x3D, 0xF4, 0xD8,
|
||||
0xC4, 0x41, 0x7D, 0xF4, 0xE1,
|
||||
0xC4, 0xC1, 0x3D, 0xF4, 0xC1,
|
||||
0xC4, 0xC1, 0x2D, 0x73, 0xD2, 0x20,
|
||||
0xC4, 0x41, 0x25, 0xEF, 0xC6,
|
||||
0xC4, 0x41, 0x25, 0xD4, 0xDC,
|
||||
0xC4, 0x41, 0x25, 0xD4, 0xDA,
|
||||
0xC4, 0x41, 0x25, 0xEF, 0xCE,
|
||||
0xC4, 0x42, 0x3D, 0x37, 0xC1,
|
||||
0xC4, 0x41, 0x3D, 0xDB, 0xC7,
|
||||
0xC5, 0xBD, 0xD4, 0xC0,
|
||||
0xC4, 0xC1, 0x25, 0x73, 0xD3, 0x20,
|
||||
0xC5, 0xA5, 0xD4, 0xC0
|
||||
};
|
||||
uint8_t* p = code + codePos;
|
||||
emit(t, code, codePos);
|
||||
p[3] += instr.dst;
|
||||
p[8] += instr.src;
|
||||
p[11] -= instr.dst * 8;
|
||||
p[13] += instr.src;
|
||||
p[17] += instr.src;
|
||||
p[20] -= instr.dst * 8;
|
||||
p[27] += instr.dst * 8;
|
||||
p[67] += instr.dst * 9;
|
||||
p[77] += instr.dst * 9;
|
||||
}
|
||||
break;
|
||||
case randomx::SuperscalarInstructionType::ISMULH_R:
|
||||
emit(REX_MOV_RR64, code, codePos);
|
||||
emitByte(0xc0 + instr.dst, code, codePos);
|
||||
emit(REX_MUL_R, code, codePos);
|
||||
emitByte(0xe8 + instr.src, code, codePos);
|
||||
emit(REX_MOV_R64R, code, codePos);
|
||||
emitByte(0xc2 + 8 * instr.dst, code, codePos);
|
||||
*(uint32_t*)(code + codePos) = 0x00C08B49UL + (instr.dst << 16);
|
||||
codePos += 3;
|
||||
*(uint32_t*)(code + codePos) = 0x00E8F749UL + (instr.src << 16);
|
||||
codePos += 3;
|
||||
*(uint32_t*)(code + codePos) = 0x00C28B4CUL + (instr.dst << 19);
|
||||
codePos += 3;
|
||||
if (AVX2) {
|
||||
static const uint8_t t[] = {
|
||||
0xC5, 0xBD, 0x73, 0xD0, 0x20,
|
||||
0xC5, 0xB5, 0x73, 0xD0, 0x20,
|
||||
0xC5, 0x7D, 0xF4, 0xD0,
|
||||
0xC5, 0x3D, 0xF4, 0xD8,
|
||||
0xC4, 0x41, 0x7D, 0xF4, 0xE1,
|
||||
0xC4, 0x41, 0x3D, 0xF4, 0xE9,
|
||||
0xC4, 0xC1, 0x2D, 0x73, 0xD2, 0x20,
|
||||
0xC4, 0x41, 0x25, 0xEF, 0xC6,
|
||||
0xC4, 0x41, 0x25, 0xD4, 0xDC,
|
||||
0xC4, 0x41, 0x25, 0xD4, 0xDA,
|
||||
0xC4, 0x41, 0x25, 0xEF, 0xCE,
|
||||
0xC4, 0x42, 0x3D, 0x37, 0xC1,
|
||||
0xC4, 0x41, 0x3D, 0xDB, 0xC7,
|
||||
0xC4, 0x41, 0x15, 0xD4, 0xE8,
|
||||
0xC4, 0xC1, 0x25, 0x73, 0xD3, 0x20,
|
||||
0xC4, 0x41, 0x15, 0xD4, 0xC3,
|
||||
0xC4, 0x41, 0x35, 0xEF, 0xC9,
|
||||
0xC4, 0x62, 0x35, 0x37, 0xD0,
|
||||
0xC4, 0x62, 0x35, 0x37, 0xD8,
|
||||
0xC5, 0x2D, 0xDB, 0xD0,
|
||||
0xC5, 0x25, 0xDB, 0xD8,
|
||||
0xC4, 0x41, 0x3D, 0xFB, 0xC2,
|
||||
0xC4, 0xC1, 0x3D, 0xFB, 0xC3
|
||||
};
|
||||
uint8_t* p = code + codePos;
|
||||
emit(t, code, codePos);
|
||||
p[3] += instr.dst;
|
||||
p[8] += instr.src;
|
||||
p[11] -= instr.dst * 8;
|
||||
p[13] += instr.src;
|
||||
p[17] += instr.src;
|
||||
p[20] -= instr.dst * 8;
|
||||
p[89] += instr.dst;
|
||||
p[94] += instr.src;
|
||||
p[98] += instr.src;
|
||||
p[102] += instr.dst;
|
||||
p[112] += instr.dst * 8;
|
||||
}
|
||||
break;
|
||||
case randomx::SuperscalarInstructionType::IMUL_RCP:
|
||||
emit(MOV_RAX_I, code, codePos);
|
||||
*(uint32_t*)(code + codePos) = 0x0000B848UL;
|
||||
codePos += 2;
|
||||
emit64(randomx_reciprocal_fast(instr.getImm32()), code, codePos);
|
||||
emit(REX_IMUL_RM, code, codePos);
|
||||
emitByte(0xc0 + 8 * instr.dst, code, codePos);
|
||||
emit32(0xC0AF0F4CUL + (instr.dst << 27), code, codePos);
|
||||
if (AVX2) {
|
||||
static const uint8_t t[] = {
|
||||
0xC4, 0x62, 0x7D, 0x19, 0x25, 0xEB, 0xFF, 0xFF, 0xFF,
|
||||
0xC5, 0xBD, 0x73, 0xD0, 0x20,
|
||||
0xC4, 0xC1, 0x35, 0x73, 0xD4, 0x20,
|
||||
0xC4, 0x41, 0x7D, 0xF4, 0xD4,
|
||||
0xC5, 0x35, 0xF4, 0xD8,
|
||||
0xC4, 0xC1, 0x3D, 0xF4, 0xC4,
|
||||
0xC4, 0xC1, 0x25, 0x73, 0xF3, 0x20,
|
||||
0xC5, 0xFD, 0x73, 0xF0, 0x20,
|
||||
0xC4, 0x41, 0x2D, 0xD4, 0xD3,
|
||||
0xC5, 0xAD, 0xD4, 0xC0
|
||||
};
|
||||
uint8_t* p = code + codePos;
|
||||
emit(t, code, codePos);
|
||||
p[12] += instr.dst;
|
||||
p[22] -= instr.dst * 8;
|
||||
p[28] += instr.dst;
|
||||
p[33] += instr.dst * 8;
|
||||
p[41] -= instr.dst * 8;
|
||||
p[43] += instr.dst;
|
||||
p[53] += instr.dst * 9;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE;
|
||||
}
|
||||
}
|
||||
|
||||
template void JitCompilerX86::generateSuperscalarCode<false>(Instruction&, uint8_t*, uint32_t&);
|
||||
template void JitCompilerX86::generateSuperscalarCode<true>(Instruction&, uint8_t*, uint32_t&);
|
||||
|
||||
template<bool rax>
|
||||
FORCE_INLINE void JitCompilerX86::genAddressReg(const Instruction& instr, const uint32_t src, uint8_t* code, uint32_t& codePos) {
|
||||
*(uint32_t*)(code + codePos) = (rax ? 0x24808d41 : 0x24888d41) + (src << 16);
|
||||
|
@ -546,10 +806,6 @@ namespace randomx {
|
|||
codePos = pos;
|
||||
}
|
||||
|
||||
void JitCompilerX86::genSIB(int scale, int index, int base, uint8_t* code, uint32_t& codePos) {
|
||||
emitByte((scale << 6) | (index << 3) | base, code, codePos);
|
||||
}
|
||||
|
||||
void JitCompilerX86::h_ISUB_R(const Instruction& instr) {
|
||||
uint8_t* const p = code;
|
||||
uint32_t pos = codePos;
|
||||
|
@ -1088,11 +1344,11 @@ namespace randomx {
|
|||
pos += 14;
|
||||
|
||||
if (jmp_offset >= -128) {
|
||||
*(uint32_t*)(p + pos) = 0x74 + (jmp_offset << 8);
|
||||
*(uint32_t*)(p + pos) = 0x74 + (static_cast<uint32_t>(jmp_offset) << 8);
|
||||
pos += 2;
|
||||
}
|
||||
else {
|
||||
*(uint64_t*)(p + pos) = 0x840f + ((static_cast<int64_t>(jmp_offset) - 4) << 16);
|
||||
*(uint64_t*)(p + pos) = 0x840f + (static_cast<uint64_t>(jmp_offset - 4) << 16);
|
||||
pos += 6;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/*
|
||||
Copyright (c) 2018-2019, tevador <tevador@gmail.com>
|
||||
Copyright (c) 2018-2020, tevador <tevador@gmail.com>
|
||||
Copyright (c) 2019-2020, SChernykh <https://github.com/SChernykh>
|
||||
Copyright (c) 2019-2020, XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -47,7 +49,7 @@ namespace randomx {
|
|||
|
||||
class JitCompilerX86 {
|
||||
public:
|
||||
explicit JitCompilerX86(bool hugePagesEnable);
|
||||
explicit JitCompilerX86(bool hugePagesEnable, bool optimizedInitDatasetEnable);
|
||||
~JitCompilerX86();
|
||||
void prepare();
|
||||
void generateProgram(Program&, ProgramConfiguration&, uint32_t);
|
||||
|
@ -55,24 +57,38 @@ namespace randomx {
|
|||
template<size_t N>
|
||||
void generateSuperscalarHash(SuperscalarProgram (&programs)[N]);
|
||||
void generateDatasetInitCode();
|
||||
ProgramFunc* getProgramFunc() {
|
||||
return (ProgramFunc*)code;
|
||||
|
||||
inline ProgramFunc *getProgramFunc() const {
|
||||
# ifdef XMRIG_SECURE_JIT
|
||||
enableExecution();
|
||||
# endif
|
||||
|
||||
return reinterpret_cast<ProgramFunc*>(code);
|
||||
}
|
||||
DatasetInitFunc* getDatasetInitFunc() {
|
||||
|
||||
inline DatasetInitFunc *getDatasetInitFunc() const {
|
||||
# ifdef XMRIG_SECURE_JIT
|
||||
enableExecution();
|
||||
# endif
|
||||
|
||||
return (DatasetInitFunc*)code;
|
||||
}
|
||||
|
||||
uint8_t* getCode() {
|
||||
return code;
|
||||
}
|
||||
size_t getCodeSize();
|
||||
void enableWriting() const;
|
||||
void enableExecution() const;
|
||||
|
||||
alignas(64) static InstructionGeneratorX86 engine[256];
|
||||
|
||||
int registerUsage[RegistersCount];
|
||||
uint8_t* code;
|
||||
uint32_t codePos;
|
||||
uint32_t codePosFirst;
|
||||
uint32_t vm_flags;
|
||||
private:
|
||||
int registerUsage[RegistersCount] = {};
|
||||
uint8_t* code = nullptr;
|
||||
uint32_t codePos = 0;
|
||||
uint32_t codePosFirst = 0;
|
||||
uint32_t vm_flags = 0;
|
||||
|
||||
# ifdef XMRIG_FIX_RYZEN
|
||||
std::pair<const void*, const void*> mainLoopBounds;
|
||||
|
@ -80,9 +96,12 @@ namespace randomx {
|
|||
|
||||
bool BranchesWithin32B = false;
|
||||
bool hasAVX;
|
||||
bool hasAVX2;
|
||||
bool initDatasetAVX2;
|
||||
bool hasXOP;
|
||||
|
||||
uint8_t* allocatedCode;
|
||||
uint8_t* allocatedCode = nullptr;
|
||||
size_t allocatedSize = 0;
|
||||
|
||||
void generateProgramPrologue(Program&, ProgramConfiguration&);
|
||||
void generateProgramEpilogue(Program&, ProgramConfiguration&);
|
||||
|
@ -90,9 +109,10 @@ namespace randomx {
|
|||
static void genAddressReg(const Instruction&, const uint32_t src, uint8_t* code, uint32_t& codePos);
|
||||
static void genAddressRegDst(const Instruction&, uint8_t* code, uint32_t& codePos);
|
||||
static void genAddressImm(const Instruction&, uint8_t* code, uint32_t& codePos);
|
||||
static void genSIB(int scale, int index, int base, uint8_t* code, uint32_t& codePos);
|
||||
static uint32_t genSIB(int scale, int index, int base) { return (scale << 6) | (index << 3) | base; }
|
||||
|
||||
void generateSuperscalarCode(Instruction &);
|
||||
template<bool AVX2>
|
||||
void generateSuperscalarCode(Instruction& inst, uint8_t* code, uint32_t& codePos);
|
||||
|
||||
static void emitByte(uint8_t val, uint8_t* code, uint32_t& codePos) {
|
||||
code[codePos] = val;
|
||||
|
@ -119,6 +139,7 @@ namespace randomx {
|
|||
codePos += count;
|
||||
}
|
||||
|
||||
public:
|
||||
void h_IADD_RS(const Instruction&);
|
||||
void h_IADD_M(const Instruction&);
|
||||
void h_ISUB_R(const Instruction&);
|
||||
|
|
|
@ -52,6 +52,11 @@
|
|||
.global DECL(randomx_program_loop_store)
|
||||
.global DECL(randomx_program_loop_end)
|
||||
.global DECL(randomx_dataset_init)
|
||||
.global DECL(randomx_dataset_init_avx2_prologue)
|
||||
.global DECL(randomx_dataset_init_avx2_loop_end)
|
||||
.global DECL(randomx_dataset_init_avx2_epilogue)
|
||||
.global DECL(randomx_dataset_init_avx2_ssh_load)
|
||||
.global DECL(randomx_dataset_init_avx2_ssh_prefetch)
|
||||
.global DECL(randomx_program_epilogue)
|
||||
.global DECL(randomx_sshash_load)
|
||||
.global DECL(randomx_sshash_prefetch)
|
||||
|
@ -192,6 +197,97 @@ call_offset:
|
|||
pop rbx
|
||||
ret
|
||||
|
||||
.balign 64
|
||||
DECL(randomx_dataset_init_avx2_prologue):
|
||||
#include "asm/program_sshash_avx2_save_registers.inc"
|
||||
|
||||
#if defined(WINABI)
|
||||
mov rdi, qword ptr [rcx] ;# cache->memory
|
||||
mov rsi, rdx ;# dataset
|
||||
mov rbp, r8 ;# block index
|
||||
push r9 ;# max. block index
|
||||
#else
|
||||
mov rdi, qword ptr [rdi] ;# cache->memory
|
||||
;# dataset in rsi
|
||||
mov rbp, rdx ;# block index
|
||||
push rcx ;# max. block index
|
||||
#endif
|
||||
sub rsp, 40
|
||||
|
||||
jmp randomx_dataset_init_avx2_prologue_loop_begin
|
||||
#include "asm/program_sshash_avx2_constants.inc"
|
||||
|
||||
.balign 64
|
||||
randomx_dataset_init_avx2_prologue_loop_begin:
|
||||
#include "asm/program_sshash_avx2_loop_begin.inc"
|
||||
|
||||
;# init integer registers (lane 0)
|
||||
lea r8, [rbp+1]
|
||||
imul r8, qword ptr [r0_avx2_mul+rip]
|
||||
mov r9, qword ptr [r1_avx2_add+rip]
|
||||
xor r9, r8
|
||||
mov r10, qword ptr [r2_avx2_add+rip]
|
||||
xor r10, r8
|
||||
mov r11, qword ptr [r3_avx2_add+rip]
|
||||
xor r11, r8
|
||||
mov r12, qword ptr [r4_avx2_add+rip]
|
||||
xor r12, r8
|
||||
mov r13, qword ptr [r5_avx2_add+rip]
|
||||
xor r13, r8
|
||||
mov r14, qword ptr [r6_avx2_add+rip]
|
||||
xor r14, r8
|
||||
mov r15, qword ptr [r7_avx2_add+rip]
|
||||
xor r15, r8
|
||||
|
||||
;# init AVX registers (lanes 1-4)
|
||||
mov qword ptr [rsp+32], rbp
|
||||
vbroadcastsd ymm0, qword ptr [rsp+32]
|
||||
vpaddq ymm0, ymm0, ymmword ptr [r0_avx2_increments+rip]
|
||||
|
||||
;# ymm0 *= r0_avx2_mul
|
||||
vbroadcastsd ymm1, qword ptr [r0_avx2_mul+rip]
|
||||
vpsrlq ymm8, ymm0, 32
|
||||
vpsrlq ymm9, ymm1, 32
|
||||
vpmuludq ymm10, ymm0, ymm1
|
||||
vpmuludq ymm11, ymm9, ymm0
|
||||
vpmuludq ymm0, ymm8, ymm1
|
||||
vpsllq ymm11, ymm11, 32
|
||||
vpsllq ymm0, ymm0, 32
|
||||
vpaddq ymm10, ymm10, ymm11
|
||||
vpaddq ymm0, ymm10, ymm0
|
||||
|
||||
vbroadcastsd ymm1, qword ptr [r1_avx2_add+rip]
|
||||
vpxor ymm1, ymm0, ymm1
|
||||
vbroadcastsd ymm2, qword ptr [r2_avx2_add+rip]
|
||||
vpxor ymm2, ymm0, ymm2
|
||||
vbroadcastsd ymm3, qword ptr [r3_avx2_add+rip]
|
||||
vpxor ymm3, ymm0, ymm3
|
||||
vbroadcastsd ymm4, qword ptr [r4_avx2_add+rip]
|
||||
vpxor ymm4, ymm0, ymm4
|
||||
vbroadcastsd ymm5, qword ptr [r5_avx2_add+rip]
|
||||
vpxor ymm5, ymm0, ymm5
|
||||
vbroadcastsd ymm6, qword ptr [r6_avx2_add+rip]
|
||||
vpxor ymm6, ymm0, ymm6
|
||||
vbroadcastsd ymm7, qword ptr [r7_avx2_add+rip]
|
||||
vpxor ymm7, ymm0, ymm7
|
||||
|
||||
vbroadcastsd ymm15, qword ptr [mul_hi_avx2_data+rip] ;# carry_bit (bit 32)
|
||||
vpsllq ymm14, ymm15, 31 ;# sign64 (bit 63)
|
||||
|
||||
;# generated SuperscalarHash code goes here
|
||||
|
||||
DECL(randomx_dataset_init_avx2_loop_end):
|
||||
#include "asm/program_sshash_avx2_loop_end.inc"
|
||||
|
||||
DECL(randomx_dataset_init_avx2_epilogue):
|
||||
#include "asm/program_sshash_avx2_epilogue.inc"
|
||||
|
||||
DECL(randomx_dataset_init_avx2_ssh_load):
|
||||
#include "asm/program_sshash_avx2_ssh_load.inc"
|
||||
|
||||
DECL(randomx_dataset_init_avx2_ssh_prefetch):
|
||||
#include "asm/program_sshash_avx2_ssh_prefetch.inc"
|
||||
|
||||
.balign 64
|
||||
DECL(randomx_program_epilogue):
|
||||
#include "asm/program_epilogue_store.inc"
|
||||
|
|
|
@ -41,6 +41,11 @@ PUBLIC randomx_program_read_dataset_ryzen
|
|||
PUBLIC randomx_program_read_dataset_sshash_init
|
||||
PUBLIC randomx_program_read_dataset_sshash_fin
|
||||
PUBLIC randomx_dataset_init
|
||||
PUBLIC randomx_dataset_init_avx2_prologue
|
||||
PUBLIC randomx_dataset_init_avx2_loop_end
|
||||
PUBLIC randomx_dataset_init_avx2_epilogue
|
||||
PUBLIC randomx_dataset_init_avx2_ssh_load
|
||||
PUBLIC randomx_dataset_init_avx2_ssh_prefetch
|
||||
PUBLIC randomx_program_loop_store
|
||||
PUBLIC randomx_program_loop_end
|
||||
PUBLIC randomx_program_epilogue
|
||||
|
@ -183,6 +188,94 @@ init_block_loop:
|
|||
randomx_dataset_init ENDP
|
||||
|
||||
ALIGN 64
|
||||
randomx_dataset_init_avx2_prologue PROC
|
||||
include asm/program_sshash_avx2_save_registers.inc
|
||||
|
||||
mov rdi, qword ptr [rcx] ;# cache->memory
|
||||
mov rsi, rdx ;# dataset
|
||||
mov rbp, r8 ;# block index
|
||||
push r9 ;# max. block index
|
||||
sub rsp, 40
|
||||
|
||||
jmp loop_begin
|
||||
include asm/program_sshash_avx2_constants.inc
|
||||
|
||||
ALIGN 64
|
||||
loop_begin:
|
||||
include asm/program_sshash_avx2_loop_begin.inc
|
||||
|
||||
;# init integer registers (lane 0)
|
||||
lea r8, [rbp+1]
|
||||
imul r8, qword ptr [r0_avx2_mul]
|
||||
mov r9, qword ptr [r1_avx2_add]
|
||||
xor r9, r8
|
||||
mov r10, qword ptr [r2_avx2_add]
|
||||
xor r10, r8
|
||||
mov r11, qword ptr [r3_avx2_add]
|
||||
xor r11, r8
|
||||
mov r12, qword ptr [r4_avx2_add]
|
||||
xor r12, r8
|
||||
mov r13, qword ptr [r5_avx2_add]
|
||||
xor r13, r8
|
||||
mov r14, qword ptr [r6_avx2_add]
|
||||
xor r14, r8
|
||||
mov r15, qword ptr [r7_avx2_add]
|
||||
xor r15, r8
|
||||
|
||||
;# init AVX registers (lanes 1-4)
|
||||
mov qword ptr [rsp+32], rbp
|
||||
vbroadcastsd ymm0, qword ptr [rsp+32]
|
||||
vpaddq ymm0, ymm0, ymmword ptr [r0_avx2_increments]
|
||||
|
||||
;# ymm0 *= r0_avx2_mul
|
||||
vbroadcastsd ymm1, qword ptr [r0_avx2_mul]
|
||||
vpsrlq ymm8, ymm0, 32
|
||||
vpsrlq ymm9, ymm1, 32
|
||||
vpmuludq ymm10, ymm0, ymm1
|
||||
vpmuludq ymm11, ymm9, ymm0
|
||||
vpmuludq ymm0, ymm8, ymm1
|
||||
vpsllq ymm11, ymm11, 32
|
||||
vpsllq ymm0, ymm0, 32
|
||||
vpaddq ymm10, ymm10, ymm11
|
||||
vpaddq ymm0, ymm10, ymm0
|
||||
|
||||
vbroadcastsd ymm1, qword ptr [r1_avx2_add]
|
||||
vpxor ymm1, ymm0, ymm1
|
||||
vbroadcastsd ymm2, qword ptr [r2_avx2_add]
|
||||
vpxor ymm2, ymm0, ymm2
|
||||
vbroadcastsd ymm3, qword ptr [r3_avx2_add]
|
||||
vpxor ymm3, ymm0, ymm3
|
||||
vbroadcastsd ymm4, qword ptr [r4_avx2_add]
|
||||
vpxor ymm4, ymm0, ymm4
|
||||
vbroadcastsd ymm5, qword ptr [r5_avx2_add]
|
||||
vpxor ymm5, ymm0, ymm5
|
||||
vbroadcastsd ymm6, qword ptr [r6_avx2_add]
|
||||
vpxor ymm6, ymm0, ymm6
|
||||
vbroadcastsd ymm7, qword ptr [r7_avx2_add]
|
||||
vpxor ymm7, ymm0, ymm7
|
||||
|
||||
vbroadcastsd ymm15, qword ptr [mul_hi_avx2_data] ;# carry_bit (bit 32)
|
||||
vpsllq ymm14, ymm15, 31 ;# sign64 (bit 63)
|
||||
randomx_dataset_init_avx2_prologue ENDP
|
||||
|
||||
;# generated SuperscalarHash code goes here
|
||||
|
||||
randomx_dataset_init_avx2_loop_end PROC
|
||||
include asm/program_sshash_avx2_loop_end.inc
|
||||
randomx_dataset_init_avx2_loop_end ENDP
|
||||
|
||||
randomx_dataset_init_avx2_epilogue PROC
|
||||
include asm/program_sshash_avx2_epilogue.inc
|
||||
randomx_dataset_init_avx2_epilogue ENDP
|
||||
|
||||
randomx_dataset_init_avx2_ssh_load PROC
|
||||
include asm/program_sshash_avx2_ssh_load.inc
|
||||
randomx_dataset_init_avx2_ssh_load ENDP
|
||||
|
||||
randomx_dataset_init_avx2_ssh_prefetch PROC
|
||||
include asm/program_sshash_avx2_ssh_prefetch.inc
|
||||
randomx_dataset_init_avx2_ssh_prefetch ENDP
|
||||
|
||||
randomx_program_epilogue PROC
|
||||
include asm/program_epilogue_store.inc
|
||||
include asm/program_epilogue_win64.inc
|
||||
|
|
|
@ -44,6 +44,11 @@ extern "C" {
|
|||
void randomx_program_loop_store();
|
||||
void randomx_program_loop_end();
|
||||
void randomx_dataset_init();
|
||||
void randomx_dataset_init_avx2_prologue();
|
||||
void randomx_dataset_init_avx2_loop_end();
|
||||
void randomx_dataset_init_avx2_epilogue();
|
||||
void randomx_dataset_init_avx2_ssh_load();
|
||||
void randomx_dataset_init_avx2_ssh_prefetch();
|
||||
void randomx_program_epilogue();
|
||||
void randomx_sshash_load();
|
||||
void randomx_sshash_prefetch();
|
||||
|
|
|
@ -53,7 +53,7 @@ extern "C" {
|
|||
#include "crypto/randomx/defyx/KangarooTwelve.h"
|
||||
}
|
||||
|
||||
#include "base/tools/Profiler.h"
|
||||
#include "crypto/rx/Profiler.h"
|
||||
|
||||
RandomX_ConfigurationWownero::RandomX_ConfigurationWownero()
|
||||
{
|
||||
|
@ -444,9 +444,9 @@ extern "C" {
|
|||
break;
|
||||
|
||||
case RANDOMX_FLAG_JIT:
|
||||
cache->jit = new randomx::JitCompiler(false);
|
||||
cache->jit = new randomx::JitCompiler(false, true);
|
||||
cache->initialize = &randomx::initCacheCompile;
|
||||
cache->datasetInit = cache->jit->getDatasetInitFunc();
|
||||
cache->datasetInit = nullptr;
|
||||
cache->memory = memory;
|
||||
break;
|
||||
|
||||
|
|
|
@ -177,6 +177,7 @@ void randomx_apply_config(const T& config)
|
|||
|
||||
void randomx_set_scratchpad_prefetch_mode(int mode);
|
||||
void randomx_set_huge_pages_jit(bool hugePages);
|
||||
void randomx_set_optimized_dataset_init(int value);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
|
|
|
@ -196,7 +196,7 @@ namespace randomx {
|
|||
int latency_;
|
||||
int resultOp_ = 0;
|
||||
int dstOp_ = 0;
|
||||
int srcOp_;
|
||||
int srcOp_ = 0;
|
||||
|
||||
SuperscalarInstructionInfo(const char* name)
|
||||
: name_(name), type_(SuperscalarInstructionType::INVALID), latency_(0) {}
|
||||
|
@ -282,11 +282,11 @@ namespace randomx {
|
|||
return fetchNextDefault(gen);
|
||||
}
|
||||
private:
|
||||
const char* name_;
|
||||
int index_;
|
||||
const int* counts_;
|
||||
int opsCount_;
|
||||
DecoderBuffer() : index_(-1) {}
|
||||
const char* name_ = nullptr;
|
||||
int index_ = -1;
|
||||
const int* counts_ = nullptr;
|
||||
int opsCount_ = 0;
|
||||
DecoderBuffer() = default;
|
||||
static const DecoderBuffer decodeBuffer484;
|
||||
static const DecoderBuffer decodeBuffer7333;
|
||||
static const DecoderBuffer decodeBuffer3733;
|
||||
|
@ -555,10 +555,10 @@ namespace randomx {
|
|||
const SuperscalarInstructionInfo* info_;
|
||||
int src_ = -1;
|
||||
int dst_ = -1;
|
||||
int mod_;
|
||||
uint32_t imm32_;
|
||||
SuperscalarInstructionType opGroup_;
|
||||
int opGroupPar_;
|
||||
int mod_ = 0;
|
||||
uint32_t imm32_ = 0;
|
||||
SuperscalarInstructionType opGroup_ = SuperscalarInstructionType::INVALID;
|
||||
int opGroupPar_ = 0;
|
||||
bool canReuse_ = false;
|
||||
bool groupParIsSource_ = false;
|
||||
|
||||
|
|
|
@ -39,13 +39,13 @@ namespace randomx {
|
|||
Instruction& operator()(int pc) {
|
||||
return programBuffer[pc];
|
||||
}
|
||||
uint32_t getSize() {
|
||||
uint32_t getSize() const {
|
||||
return size;
|
||||
}
|
||||
void setSize(uint32_t val) {
|
||||
size = val;
|
||||
}
|
||||
int getAddressRegister() {
|
||||
int getAddressRegister() const {
|
||||
return addrReg;
|
||||
}
|
||||
void setAddressRegister(int val) {
|
||||
|
|
|
@ -30,13 +30,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <iomanip>
|
||||
#include <stdexcept>
|
||||
#include "crypto/randomx/virtual_machine.hpp"
|
||||
#include "crypto/randomx/common.hpp"
|
||||
#include "crypto/randomx/aes_hash.hpp"
|
||||
#include "crypto/randomx/blake2/blake2.h"
|
||||
#include "crypto/randomx/intrin_portable.h"
|
||||
#include "crypto/randomx/allocator.hpp"
|
||||
#include "crypto/randomx/blake2/blake2.h"
|
||||
#include "crypto/randomx/common.hpp"
|
||||
#include "crypto/randomx/intrin_portable.h"
|
||||
#include "crypto/randomx/soft_aes.h"
|
||||
#include "base/tools/Profiler.h"
|
||||
#include "crypto/rx/Profiler.h"
|
||||
|
||||
randomx_vm::~randomx_vm() {
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/*
|
||||
Copyright (c) 2018-2019, tevador <tevador@gmail.com>
|
||||
Copyright (c) 2018-2020, tevador <tevador@gmail.com>
|
||||
Copyright (c) 2019-2020, SChernykh <https://github.com/SChernykh>
|
||||
Copyright (c) 2019-2020, XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -28,7 +30,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "crypto/randomx/vm_compiled.hpp"
|
||||
#include "crypto/randomx/common.hpp"
|
||||
#include "base/tools/Profiler.h"
|
||||
#include "crypto/rx/Profiler.h"
|
||||
|
||||
namespace randomx {
|
||||
|
||||
|
@ -56,9 +58,9 @@ namespace randomx {
|
|||
void CompiledVm<softAes>::execute() {
|
||||
PROFILE_SCOPE(RandomX_JIT_execute);
|
||||
|
||||
#ifdef XMRIG_ARM
|
||||
# ifdef XMRIG_ARM
|
||||
memcpy(reg.f, config.eMask, sizeof(config.eMask));
|
||||
#endif
|
||||
# endif
|
||||
compiler.getProgramFunc()(reg, mem, scratchpad, RandomX_CurrentConfig.ProgramIterations);
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ namespace randomx {
|
|||
protected:
|
||||
void execute();
|
||||
|
||||
JitCompiler compiler{ true };
|
||||
JitCompiler compiler{ true, false };
|
||||
};
|
||||
|
||||
using CompiledVmDefault = CompiledVm<1>;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
/*
|
||||
Copyright (c) 2018-2019, tevador <tevador@gmail.com>
|
||||
Copyright (c) 2018-2020, tevador <tevador@gmail.com>
|
||||
Copyright (c) 2019-2020, SChernykh <https://github.com/SChernykh>
|
||||
Copyright (c) 2019-2020, XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
|
||||
All rights reserved.
|
||||
|
||||
|
@ -36,6 +38,11 @@ namespace randomx {
|
|||
void CompiledLightVm<softAes>::setCache(randomx_cache* cache) {
|
||||
cachePtr = cache;
|
||||
mem.memory = cache->memory;
|
||||
|
||||
# ifdef XMRIG_SECURE_JIT
|
||||
compiler.enableWriting();
|
||||
# endif
|
||||
|
||||
compiler.generateSuperscalarHash(cache->programs);
|
||||
}
|
||||
|
||||
|
@ -43,7 +50,13 @@ namespace randomx {
|
|||
void CompiledLightVm<softAes>::run(void* seed) {
|
||||
VmBase<softAes>::generateProgram(seed);
|
||||
randomx_vm::initialize();
|
||||
|
||||
# ifdef XMRIG_SECURE_JIT
|
||||
compiler.enableWriting();
|
||||
# endif
|
||||
|
||||
compiler.generateProgramLight(program, config, datasetOffset);
|
||||
|
||||
CompiledVm<softAes>::execute();
|
||||
}
|
||||
|
||||
|
|
103
src/crypto/rx/Profiler.cpp
Normal file
103
src/crypto/rx/Profiler.cpp
Normal file
|
@ -0,0 +1,103 @@
|
|||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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/rx/Profiler.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/io/log/Tags.h"
|
||||
|
||||
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_PROFILING
|
||||
|
||||
|
||||
ProfileScopeData* ProfileScopeData::s_data[MAX_DATA_COUNT] = {};
|
||||
volatile long ProfileScopeData::s_dataCount = 0;
|
||||
double ProfileScopeData::s_tscSpeed = 0.0;
|
||||
|
||||
|
||||
#ifndef NOINLINE
|
||||
#ifdef __GNUC__
|
||||
#define NOINLINE __attribute__ ((noinline))
|
||||
#elif _MSC_VER
|
||||
#define NOINLINE __declspec(noinline)
|
||||
#else
|
||||
#define NOINLINE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
static std::string get_thread_id()
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::this_thread::get_id();
|
||||
|
||||
std::string s = ss.str();
|
||||
if (s.length() > ProfileScopeData::MAX_THREAD_ID_LENGTH) {
|
||||
s.resize(ProfileScopeData::MAX_THREAD_ID_LENGTH);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
NOINLINE void ProfileScopeData::Register(ProfileScopeData* data)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
const long id = _InterlockedIncrement(&s_dataCount) - 1;
|
||||
#else
|
||||
const long id = __sync_fetch_and_add(&s_dataCount, 1);
|
||||
#endif
|
||||
|
||||
if (static_cast<unsigned long>(id) < MAX_DATA_COUNT) {
|
||||
s_data[id] = data;
|
||||
|
||||
const std::string s = get_thread_id();
|
||||
memcpy(data->m_threadId, s.c_str(), s.length() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NOINLINE void ProfileScopeData::Init()
|
||||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
const uint64_t t1 = static_cast<uint64_t>(time_point_cast<nanoseconds>(high_resolution_clock::now()).time_since_epoch().count());
|
||||
const uint64_t count1 = ReadTSC();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const uint64_t t2 = static_cast<uint64_t>(time_point_cast<nanoseconds>(high_resolution_clock::now()).time_since_epoch().count());
|
||||
const uint64_t count2 = ReadTSC();
|
||||
|
||||
if (t2 - t1 > 1000000000) {
|
||||
s_tscSpeed = (count2 - count1) * 1e9 / (t2 - t1);
|
||||
LOG_INFO("%s TSC speed = %.3f GHz", xmrig::Tags::profiler(), s_tscSpeed / 1e9);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* XMRIG_FEATURE_PROFILING */
|
133
src/crypto/rx/Profiler.h
Normal file
133
src/crypto/rx/Profiler.h
Normal file
|
@ -0,0 +1,133 @@
|
|||
/* XMRig
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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_PROFILER_H
|
||||
#define XMRIG_PROFILER_H
|
||||
|
||||
|
||||
#ifndef FORCE_INLINE
|
||||
#if defined(_MSC_VER)
|
||||
#define FORCE_INLINE __forceinline
|
||||
#elif defined(__GNUC__)
|
||||
#define FORCE_INLINE __attribute__((always_inline)) inline
|
||||
#elif defined(__clang__)
|
||||
#define FORCE_INLINE __inline__
|
||||
#else
|
||||
#define FORCE_INLINE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef XMRIG_FEATURE_PROFILING
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
|
||||
static FORCE_INLINE uint64_t ReadTSC()
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
return __rdtsc();
|
||||
#else
|
||||
uint32_t hi, lo;
|
||||
__asm__ __volatile__("rdtsc" : "=a"(lo), "=d"(hi));
|
||||
return (((uint64_t)hi) << 32) | lo;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
struct ProfileScopeData
|
||||
{
|
||||
const char* m_name;
|
||||
uint64_t m_totalCycles;
|
||||
uint32_t m_totalSamples;
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_THREAD_ID_LENGTH = 11,
|
||||
MAX_SAMPLE_COUNT = 128,
|
||||
MAX_DATA_COUNT = 1024
|
||||
};
|
||||
|
||||
char m_threadId[MAX_THREAD_ID_LENGTH + 1];
|
||||
|
||||
static ProfileScopeData* s_data[MAX_DATA_COUNT];
|
||||
static volatile long s_dataCount;
|
||||
static double s_tscSpeed;
|
||||
|
||||
static void Register(ProfileScopeData* data);
|
||||
static void Init();
|
||||
};
|
||||
|
||||
static_assert(std::is_trivial<ProfileScopeData>::value, "ProfileScopeData must be a trivial struct");
|
||||
static_assert(sizeof(ProfileScopeData) <= 32, "ProfileScopeData struct is too big");
|
||||
|
||||
|
||||
class ProfileScope
|
||||
{
|
||||
public:
|
||||
FORCE_INLINE ProfileScope(ProfileScopeData& data)
|
||||
: m_data(data)
|
||||
{
|
||||
if (m_data.m_totalCycles == 0) {
|
||||
ProfileScopeData::Register(&data);
|
||||
}
|
||||
|
||||
m_startCounter = ReadTSC();
|
||||
}
|
||||
|
||||
FORCE_INLINE ~ProfileScope()
|
||||
{
|
||||
m_data.m_totalCycles += ReadTSC() - m_startCounter;
|
||||
++m_data.m_totalSamples;
|
||||
}
|
||||
|
||||
private:
|
||||
ProfileScopeData& m_data;
|
||||
uint64_t m_startCounter;
|
||||
};
|
||||
|
||||
|
||||
#define PROFILE_SCOPE(x) static thread_local ProfileScopeData x##_data{#x}; ProfileScope x(x##_data);
|
||||
|
||||
|
||||
#else /* XMRIG_FEATURE_PROFILING */
|
||||
#define PROFILE_SCOPE(x)
|
||||
#endif /* XMRIG_FEATURE_PROFILING */
|
||||
|
||||
|
||||
#include "crypto/randomx/blake2/blake2.h"
|
||||
|
||||
|
||||
struct rx_blake2b_wrapper
|
||||
{
|
||||
FORCE_INLINE static void run(void* out, size_t outlen, const void* in, size_t inlen)
|
||||
{
|
||||
PROFILE_SCOPE(RandomX_Blake2b);
|
||||
rx_blake2b(out, outlen, in, inlen);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif /* XMRIG_PROFILER_H */
|
|
@ -1,14 +1,7 @@
|
|||
/* 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-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
@ -103,6 +96,7 @@ bool xmrig::Rx::init(const T &seed, const RxConfig &config, const CpuConfig &cpu
|
|||
|
||||
randomx_set_scratchpad_prefetch_mode(config.scratchpadPrefetchMode());
|
||||
randomx_set_huge_pages_jit(cpu.isHugePagesJit());
|
||||
randomx_set_optimized_dataset_init(config.initDatasetAVX2());
|
||||
|
||||
if (!msrInitialized) {
|
||||
msrEnabled = msrInit(config, cpu.threads().get(seed.algorithm()).data());
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
/* 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-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
/* 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-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
/* 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-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
/* 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-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
@ -30,7 +23,6 @@
|
|||
#include "base/io/log/Log.h"
|
||||
#include "base/io/log/Tags.h"
|
||||
#include "base/tools/Chrono.h"
|
||||
#include "base/tools/Object.h"
|
||||
#include "crypto/rx/RxAlgo.h"
|
||||
#include "crypto/rx/RxCache.h"
|
||||
#include "crypto/rx/RxDataset.h"
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
/* 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-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
@ -29,7 +22,6 @@
|
|||
|
||||
|
||||
#include "backend/common/interfaces/IRxStorage.h"
|
||||
#include "base/tools/Object.h"
|
||||
|
||||
|
||||
namespace xmrig
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
namespace xmrig {
|
||||
|
||||
const char *RxConfig::kInit = "init";
|
||||
const char *RxConfig::kInitAVX2 = "init-avx2";
|
||||
const char *RxConfig::kField = "randomx";
|
||||
const char *RxConfig::kMode = "mode";
|
||||
const char *RxConfig::kOneGbPages = "1gb-pages";
|
||||
|
@ -86,9 +87,10 @@ static_assert (kMsrArraySize == ICpuInfo::MSR_MOD_MAX, "kMsrArraySize and MSR_MO
|
|||
bool xmrig::RxConfig::read(const rapidjson::Value &value)
|
||||
{
|
||||
if (value.IsObject()) {
|
||||
m_threads = Json::getInt(value, kInit, m_threads);
|
||||
m_mode = readMode(Json::getValue(value, kMode));
|
||||
m_rdmsr = Json::getBool(value, kRdmsr, m_rdmsr);
|
||||
m_threads = Json::getInt(value, kInit, m_threads);
|
||||
m_initDatasetAVX2 = Json::getInt(value, kInitAVX2, m_initDatasetAVX2);
|
||||
m_mode = readMode(Json::getValue(value, kMode));
|
||||
m_rdmsr = Json::getBool(value, kRdmsr, m_rdmsr);
|
||||
|
||||
# ifdef XMRIG_FEATURE_MSR
|
||||
readMSR(Json::getValue(value, kWrmsr));
|
||||
|
@ -122,7 +124,7 @@ bool xmrig::RxConfig::read(const rapidjson::Value &value)
|
|||
}
|
||||
# endif
|
||||
|
||||
const uint32_t mode = static_cast<uint32_t>(Json::getInt(value, kScratchpadPrefetchMode, static_cast<int>(m_scratchpadPrefetchMode)));
|
||||
const auto mode = static_cast<uint32_t>(Json::getInt(value, kScratchpadPrefetchMode, static_cast<int>(m_scratchpadPrefetchMode)));
|
||||
if (mode < ScratchpadPrefetchMax) {
|
||||
m_scratchpadPrefetchMode = static_cast<ScratchpadPrefetchMode>(mode);
|
||||
}
|
||||
|
@ -141,6 +143,7 @@ rapidjson::Value xmrig::RxConfig::toJSON(rapidjson::Document &doc) const
|
|||
|
||||
Value obj(kObjectType);
|
||||
obj.AddMember(StringRef(kInit), m_threads, allocator);
|
||||
obj.AddMember(StringRef(kInitAVX2), m_initDatasetAVX2, allocator);
|
||||
obj.AddMember(StringRef(kMode), StringRef(modeName()), allocator);
|
||||
obj.AddMember(StringRef(kOneGbPages), m_oneGbPages, allocator);
|
||||
obj.AddMember(StringRef(kRdmsr), m_rdmsr, allocator);
|
||||
|
|
|
@ -61,6 +61,7 @@ public:
|
|||
static const char *kCacheQoS;
|
||||
static const char *kField;
|
||||
static const char *kInit;
|
||||
static const char *kInitAVX2;
|
||||
static const char *kMode;
|
||||
static const char *kOneGbPages;
|
||||
static const char *kRdmsr;
|
||||
|
@ -83,6 +84,7 @@ public:
|
|||
const char *modeName() const;
|
||||
uint32_t threads(uint32_t limit = 100) const;
|
||||
|
||||
inline int initDatasetAVX2() const { return m_initDatasetAVX2; }
|
||||
inline bool isOneGbPages() const { return m_oneGbPages; }
|
||||
inline bool rdmsr() const { return m_rdmsr; }
|
||||
inline bool wrmsr() const { return m_wrmsr; }
|
||||
|
@ -111,11 +113,12 @@ private:
|
|||
|
||||
Mode readMode(const rapidjson::Value &value) const;
|
||||
|
||||
bool m_numa = true;
|
||||
bool m_oneGbPages = false;
|
||||
bool m_rdmsr = true;
|
||||
int m_threads = -1;
|
||||
Mode m_mode = AutoMode;
|
||||
bool m_numa = true;
|
||||
bool m_oneGbPages = false;
|
||||
bool m_rdmsr = true;
|
||||
int m_threads = -1;
|
||||
int m_initDatasetAVX2 = -1;
|
||||
Mode m_mode = AutoMode;
|
||||
|
||||
ScratchpadPrefetchMode m_scratchpadPrefetchMode = ScratchpadPrefetchT0;
|
||||
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
/* 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-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
@ -26,10 +19,12 @@
|
|||
|
||||
|
||||
#include "crypto/rx/RxDataset.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/io/log/Tags.h"
|
||||
#include "base/kernel/Platform.h"
|
||||
#include "crypto/common/VirtualMemory.h"
|
||||
#include "crypto/randomx/randomx.h"
|
||||
#include "crypto/rx/RxAlgo.h"
|
||||
#include "crypto/rx/RxCache.h"
|
||||
|
||||
|
@ -45,7 +40,13 @@ static void init_dataset_wrapper(randomx_dataset *dataset, randomx_cache *cache,
|
|||
{
|
||||
Platform::setThreadPriority(priority);
|
||||
|
||||
randomx_init_dataset(dataset, cache, startItem, itemCount);
|
||||
if (Cpu::info()->hasAVX2() && (itemCount % 5)) {
|
||||
randomx_init_dataset(dataset, cache, startItem, itemCount - (itemCount % 5));
|
||||
randomx_init_dataset(dataset, cache, startItem + itemCount - 5, 5);
|
||||
}
|
||||
else {
|
||||
randomx_init_dataset(dataset, cache, startItem, itemCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -162,6 +163,22 @@ size_t xmrig::RxDataset::size(bool cache) const
|
|||
}
|
||||
|
||||
|
||||
uint8_t *xmrig::RxDataset::tryAllocateScrathpad()
|
||||
{
|
||||
auto p = reinterpret_cast<uint8_t *>(raw());
|
||||
if (!p) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const size_t offset = m_scratchpadOffset.fetch_add(RANDOMX_SCRATCHPAD_L3_MAX_SIZE);
|
||||
if (offset + RANDOMX_SCRATCHPAD_L3_MAX_SIZE > m_scratchpadLimit) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return p + offset;
|
||||
}
|
||||
|
||||
|
||||
void *xmrig::RxDataset::raw() const
|
||||
{
|
||||
return m_dataset ? randomx_get_dataset_memory(m_dataset) : nullptr;
|
||||
|
@ -208,19 +225,3 @@ void xmrig::RxDataset::allocate(bool hugePages, bool oneGbPages)
|
|||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
uint8_t* xmrig::RxDataset::tryAllocateScrathpad()
|
||||
{
|
||||
uint8_t* p = reinterpret_cast<uint8_t*>(raw());
|
||||
if (!p) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const size_t offset = m_scratchpadOffset.fetch_add(RANDOMX_SCRATCHPAD_L3_MAX_SIZE);
|
||||
if (offset + RANDOMX_SCRATCHPAD_L3_MAX_SIZE > m_scratchpadLimit) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return p + offset;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
/* 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-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
@ -28,12 +21,10 @@
|
|||
#define XMRIG_RX_DATASET_H
|
||||
|
||||
|
||||
#include "base/crypto/Algorithm.h"
|
||||
#include "base/tools/Buffer.h"
|
||||
#include "base/tools/Object.h"
|
||||
#include "crypto/common/HugePagesInfo.h"
|
||||
#include "crypto/randomx/configuration.h"
|
||||
#include "crypto/randomx/randomx.h"
|
||||
#include "crypto/rx/RxConfig.h"
|
||||
|
||||
#include <atomic>
|
||||
|
@ -68,11 +59,10 @@ public:
|
|||
bool isOneGbPages() const;
|
||||
HugePagesInfo hugePages(bool cache = true) const;
|
||||
size_t size(bool cache = true) const;
|
||||
uint8_t *tryAllocateScrathpad();
|
||||
void *raw() const;
|
||||
void setRaw(const void *raw);
|
||||
|
||||
uint8_t *tryAllocateScrathpad();
|
||||
|
||||
static inline constexpr size_t maxSize() { return RANDOMX_DATASET_MAX_SIZE; }
|
||||
|
||||
private:
|
||||
|
@ -82,10 +72,9 @@ private:
|
|||
const uint32_t m_node;
|
||||
randomx_dataset *m_dataset = nullptr;
|
||||
RxCache *m_cache = nullptr;
|
||||
VirtualMemory *m_memory = nullptr;
|
||||
|
||||
std::atomic<size_t> m_scratchpadOffset;
|
||||
size_t m_scratchpadLimit = 0;
|
||||
std::atomic<size_t> m_scratchpadOffset{};
|
||||
VirtualMemory *m_memory = nullptr;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
/* 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-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
@ -32,7 +25,6 @@
|
|||
#include "base/io/log/Tags.h"
|
||||
#include "base/kernel/Platform.h"
|
||||
#include "base/tools/Chrono.h"
|
||||
#include "base/tools/Object.h"
|
||||
#include "crypto/rx/RxAlgo.h"
|
||||
#include "crypto/rx/RxCache.h"
|
||||
#include "crypto/rx/RxDataset.h"
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
/* 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-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
@ -29,7 +22,6 @@
|
|||
|
||||
|
||||
#include "backend/common/interfaces/IRxStorage.h"
|
||||
#include "base/tools/Object.h"
|
||||
|
||||
|
||||
#include <vector>
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "base/io/Async.h"
|
||||
#include "base/io/log/Log.h"
|
||||
#include "base/io/log/Tags.h"
|
||||
#include "base/tools/Cvt.h"
|
||||
#include "crypto/rx/RxBasicStorage.h"
|
||||
|
||||
|
||||
|
@ -149,12 +150,12 @@ void xmrig::RxQueue::backgroundInit()
|
|||
item.nodeset.size() > 1 ? "s" : "",
|
||||
item.seed.algorithm().shortName(),
|
||||
item.threads,
|
||||
Buffer::toHex(item.seed.data().data(), 8).data()
|
||||
Cvt::toHex(item.seed.data().data(), 8).data()
|
||||
);
|
||||
|
||||
m_storage->init(item.seed, item.threads, item.hugePages, item.oneGbPages, item.mode, item.priority);
|
||||
|
||||
lock = std::unique_lock<std::mutex>(m_mutex);
|
||||
lock.lock();
|
||||
|
||||
if (m_state == STATE_SHUTDOWN || !m_queue.empty()) {
|
||||
continue;
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
/* 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-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
@ -26,6 +19,7 @@
|
|||
|
||||
|
||||
#include "crypto/randomx/randomx.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
#include "crypto/rx/RxCache.h"
|
||||
#include "crypto/rx/RxDataset.h"
|
||||
#include "crypto/rx/RxVm.h"
|
||||
|
@ -36,7 +30,7 @@ extern "C" uint32_t rx_blake2b_use_sse41;
|
|||
#endif
|
||||
|
||||
|
||||
randomx_vm* xmrig::RxVm::create(RxDataset *dataset, uint8_t *scratchpad, bool softAes, xmrig::Assembly assembly, uint32_t node)
|
||||
randomx_vm *xmrig::RxVm::create(RxDataset *dataset, uint8_t *scratchpad, bool softAes, const Assembly &assembly, uint32_t node)
|
||||
{
|
||||
int flags = 0;
|
||||
|
||||
|
@ -52,11 +46,8 @@ randomx_vm* xmrig::RxVm::create(RxDataset *dataset, uint8_t *scratchpad, bool so
|
|||
flags |= RANDOMX_FLAG_JIT;
|
||||
}
|
||||
|
||||
if (assembly == Assembly::AUTO) {
|
||||
assembly = Cpu::info()->assembly();
|
||||
}
|
||||
|
||||
if ((assembly == Assembly::RYZEN) || (assembly == Assembly::BULLDOZER)) {
|
||||
const auto asmId = assembly == Assembly::AUTO ? Cpu::info()->assembly() : assembly.id();
|
||||
if ((asmId == Assembly::RYZEN) || (asmId == Assembly::BULLDOZER)) {
|
||||
flags |= RANDOMX_FLAG_AMD;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,7 @@
|
|||
/* 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-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
@ -28,10 +21,6 @@
|
|||
#define XMRIG_RX_VM_H
|
||||
|
||||
|
||||
#include "base/tools/Object.h"
|
||||
#include "backend/cpu/Cpu.h"
|
||||
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
|
||||
|
@ -42,16 +31,15 @@ namespace xmrig
|
|||
{
|
||||
|
||||
|
||||
class Assembly;
|
||||
class RxDataset;
|
||||
|
||||
|
||||
class RxVm
|
||||
{
|
||||
public:
|
||||
XMRIG_DISABLE_COPY_MOVE_DEFAULT(RxVm);
|
||||
|
||||
static randomx_vm* create(RxDataset *dataset, uint8_t *scratchpad, bool softAes, xmrig::Assembly assembly, uint32_t node);
|
||||
static void destroy(randomx_vm* vm);
|
||||
static randomx_vm *create(RxDataset *dataset, uint8_t *scratchpad, bool softAes, const Assembly &assembly, uint32_t node);
|
||||
static void destroy(randomx_vm *vm);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
/* 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-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2000 Transmeta Corporation <https://github.com/intel/msr-tools>
|
||||
* Copyright 2004-2008 H. Peter Anvin <https://github.com/intel/msr-tools>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2000 Transmeta Corporation <https://github.com/intel/msr-tools>
|
||||
* Copyright (c) 2004-2008 H. Peter Anvin <https://github.com/intel/msr-tools>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
@ -110,7 +103,7 @@ static bool wrmsr_on_cpu(uint32_t reg, uint32_t cpu, uint64_t value, uint64_t ma
|
|||
|
||||
char msr_file_name[64]{};
|
||||
|
||||
sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu);
|
||||
sprintf(msr_file_name, "/dev/cpu/%u/msr", cpu);
|
||||
int fd = open(msr_file_name, O_WRONLY);
|
||||
if (fd < 0) {
|
||||
return false;
|
||||
|
|
|
@ -1,17 +1,10 @@
|
|||
/* 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-2019 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
|
||||
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
|
||||
* Copyright 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright 2000 Transmeta Corporation <https://github.com/intel/msr-tools>
|
||||
* Copyright 2004-2008 H. Peter Anvin <https://github.com/intel/msr-tools>
|
||||
* Copyright 2007-2009 hiyohiyo <https://openlibsys.org>, <hiyohiyo@crystalmark.info>
|
||||
* Copyright 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright 2016-2020 XMRig <https://github.com/xmrig>, <support@xmrig.com>
|
||||
* Copyright (c) 2018-2019 tevador <tevador@gmail.com>
|
||||
* Copyright (c) 2000 Transmeta Corporation <https://github.com/intel/msr-tools>
|
||||
* Copyright (c) 2004-2008 H. Peter Anvin <https://github.com/intel/msr-tools>
|
||||
* Copyright (c) 2007-2009 hiyohiyo <https://openlibsys.org>, <hiyohiyo@crystalmark.info>
|
||||
* Copyright (c) 2018-2020 SChernykh <https://github.com/SChernykh>
|
||||
* Copyright (c) 2016-2020 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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue