mirror of
https://git.wownero.com/wownero/RandomWOW.git
synced 2024-12-22 07:48:54 +00:00
randomx_cache and randomx_dataset changed to standard-layout structs
This commit is contained in:
parent
fd7186f873
commit
22a3aa8d79
@ -113,6 +113,10 @@ namespace randomx {
|
|||||||
typedef void(*DatasetReadFunc)(addr_t, MemoryRegisters&, int_reg_t(®)[RegistersCount]);
|
typedef void(*DatasetReadFunc)(addr_t, MemoryRegisters&, int_reg_t(®)[RegistersCount]);
|
||||||
typedef void(*ProgramFunc)(RegisterFile&, MemoryRegisters&, uint8_t* /* scratchpad */, uint64_t);
|
typedef void(*ProgramFunc)(RegisterFile&, MemoryRegisters&, uint8_t* /* scratchpad */, uint64_t);
|
||||||
typedef void(*DatasetInitFunc)(randomx_cache* cache, uint8_t* dataset, uint32_t startBlock, uint32_t endBlock);
|
typedef void(*DatasetInitFunc)(randomx_cache* cache, uint8_t* dataset, uint32_t startBlock, uint32_t endBlock);
|
||||||
|
|
||||||
|
typedef void(*DatasetDeallocFunc)(randomx_dataset*);
|
||||||
|
typedef void(*CacheDeallocFunc)(randomx_cache*);
|
||||||
|
typedef void(*CacheInitializeFunc)(randomx_cache*, const void*, size_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const randomx::RegisterFile& rf);
|
std::ostream& operator<<(std::ostream& os, const randomx::RegisterFile& rf);
|
||||||
|
@ -40,14 +40,12 @@ along with RandomX. If not, see<http://www.gnu.org/licenses/>.
|
|||||||
#include "argon2.h"
|
#include "argon2.h"
|
||||||
#include "argon2_core.h"
|
#include "argon2_core.h"
|
||||||
|
|
||||||
randomx_dataset::~randomx_dataset() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static_assert(RANDOMX_ARGON_MEMORY % (RANDOMX_ARGON_LANES * ARGON2_SYNC_POINTS) == 0, "RANDOMX_ARGON_MEMORY - invalid value");
|
static_assert(RANDOMX_ARGON_MEMORY % (RANDOMX_ARGON_LANES * ARGON2_SYNC_POINTS) == 0, "RANDOMX_ARGON_MEMORY - invalid value");
|
||||||
static_assert(ARGON2_BLOCK_SIZE == randomx::ArgonBlockSize, "Unpexpected value of ARGON2_BLOCK_SIZE");
|
static_assert(ARGON2_BLOCK_SIZE == randomx::ArgonBlockSize, "Unpexpected value of ARGON2_BLOCK_SIZE");
|
||||||
|
|
||||||
void randomx_cache::initialize(const void *seed, size_t seedSize) {
|
namespace randomx {
|
||||||
|
|
||||||
|
void initCache(randomx_cache* cache, const void* seed, size_t seedSize) {
|
||||||
uint32_t memory_blocks, segment_length;
|
uint32_t memory_blocks, segment_length;
|
||||||
argon2_instance_t instance;
|
argon2_instance_t instance;
|
||||||
argon2_context context;
|
argon2_context context;
|
||||||
@ -86,7 +84,7 @@ void randomx_cache::initialize(const void *seed, size_t seedSize) {
|
|||||||
instance.lanes = context.lanes;
|
instance.lanes = context.lanes;
|
||||||
instance.threads = context.threads;
|
instance.threads = context.threads;
|
||||||
instance.type = Argon2_d;
|
instance.type = Argon2_d;
|
||||||
instance.memory = (block*)memory;
|
instance.memory = (block*)cache->memory;
|
||||||
|
|
||||||
if (instance.threads > instance.lanes) {
|
if (instance.threads > instance.lanes) {
|
||||||
instance.threads = instance.lanes;
|
instance.threads = instance.lanes;
|
||||||
@ -99,67 +97,27 @@ void randomx_cache::initialize(const void *seed, size_t seedSize) {
|
|||||||
|
|
||||||
fill_memory_blocks(&instance);
|
fill_memory_blocks(&instance);
|
||||||
|
|
||||||
reciprocalCache.clear();
|
cache->reciprocalCache.clear();
|
||||||
randomx::Blake2Generator gen(seed, seedSize);
|
randomx::Blake2Generator gen(seed, seedSize);
|
||||||
for (int i = 0; i < RANDOMX_CACHE_ACCESSES; ++i) {
|
for (int i = 0; i < RANDOMX_CACHE_ACCESSES; ++i) {
|
||||||
randomx::generateSuperscalar(programs[i], gen);
|
randomx::generateSuperscalar(cache->programs[i], gen);
|
||||||
for (unsigned j = 0; j < programs[i].getSize(); ++j) {
|
for (unsigned j = 0; j < cache->programs[i].getSize(); ++j) {
|
||||||
auto& instr = programs[i](j);
|
auto& instr = cache->programs[i](j);
|
||||||
if (instr.opcode == randomx::SuperscalarInstructionType::IMUL_RCP) {
|
if (instr.opcode == randomx::SuperscalarInstructionType::IMUL_RCP) {
|
||||||
auto rcp = randomx_reciprocal(instr.getImm32());
|
auto rcp = randomx_reciprocal(instr.getImm32());
|
||||||
instr.setImm32(reciprocalCache.size());
|
instr.setImm32(cache->reciprocalCache.size());
|
||||||
reciprocalCache.push_back(rcp);
|
cache->reciprocalCache.push_back(rcp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace randomx {
|
void initCacheCompile(randomx_cache* cache, const void* seed, size_t seedSize) {
|
||||||
|
initCache(cache, seed, seedSize);
|
||||||
template<class Allocator>
|
cache->jit->generateSuperscalarHash(cache->programs, cache->reciprocalCache);
|
||||||
void Dataset<Allocator>::allocate() {
|
cache->jit->generateDatasetInitCode();
|
||||||
memory = (uint8_t*)Allocator::allocMemory(DatasetSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Allocator>
|
|
||||||
Dataset<Allocator>::~Dataset() {
|
|
||||||
Allocator::freeMemory(memory, DatasetSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Allocator>
|
|
||||||
void Cache<Allocator>::allocate() {
|
|
||||||
memory = (uint8_t*)Allocator::allocMemory(CacheSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Allocator>
|
|
||||||
Cache<Allocator>::~Cache() {
|
|
||||||
Allocator::freeMemory(memory, CacheSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Allocator>
|
|
||||||
DatasetInitFunc Cache<Allocator>::getInitFunc() {
|
|
||||||
return &initDataset;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Allocator>
|
|
||||||
DatasetInitFunc CacheWithJit<Allocator>::getInitFunc() {
|
|
||||||
return jit.getDatasetInitFunc();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Allocator>
|
|
||||||
void CacheWithJit<Allocator>::initialize(const void *seed, size_t seedSize) {
|
|
||||||
randomx_cache::initialize(seed, seedSize);
|
|
||||||
jit.generateSuperscalarHash(programs, reciprocalCache);
|
|
||||||
jit.generateDatasetInitCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
template class Dataset<AlignedAllocator<CacheLineSize>>;
|
|
||||||
template class Dataset<LargePageAllocator>;
|
|
||||||
template class Cache<AlignedAllocator<CacheLineSize>>;
|
|
||||||
template class Cache<LargePageAllocator>;
|
|
||||||
template class CacheWithJit<AlignedAllocator<CacheLineSize>>;
|
|
||||||
template class CacheWithJit<LargePageAllocator>;
|
|
||||||
|
|
||||||
constexpr uint64_t superscalarMul0 = 6364136223846793005ULL;
|
constexpr uint64_t superscalarMul0 = 6364136223846793005ULL;
|
||||||
constexpr uint64_t superscalarAdd1 = 9298411001130361340ULL;
|
constexpr uint64_t superscalarAdd1 = 9298411001130361340ULL;
|
||||||
constexpr uint64_t superscalarAdd2 = 12065312585734608966ULL;
|
constexpr uint64_t superscalarAdd2 = 12065312585734608966ULL;
|
||||||
|
@ -21,6 +21,7 @@ along with RandomX. If not, see<http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <type_traits>
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
#include "superscalar_program.hpp"
|
#include "superscalar_program.hpp"
|
||||||
#include "jit_compiler_x86.hpp"
|
#include "jit_compiler_x86.hpp"
|
||||||
@ -28,51 +29,45 @@ along with RandomX. If not, see<http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
/* Global scope for C binding */
|
/* Global scope for C binding */
|
||||||
struct randomx_dataset {
|
struct randomx_dataset {
|
||||||
virtual ~randomx_dataset() = 0;
|
|
||||||
virtual void allocate() = 0;
|
|
||||||
uint8_t* memory = nullptr;
|
uint8_t* memory = nullptr;
|
||||||
|
randomx::DatasetDeallocFunc dealloc;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Global scope for C binding */
|
/* Global scope for C binding */
|
||||||
struct randomx_cache : public randomx_dataset {
|
struct randomx_cache {
|
||||||
virtual randomx::DatasetInitFunc getInitFunc() = 0;
|
uint8_t* memory = nullptr;
|
||||||
virtual void initialize(const void *seed, size_t seedSize);
|
randomx::CacheDeallocFunc dealloc;
|
||||||
|
randomx::JitCompilerX86* jit;
|
||||||
|
randomx::CacheInitializeFunc initialize;
|
||||||
|
randomx::DatasetInitFunc datasetInit;
|
||||||
randomx::SuperscalarProgram programs[RANDOMX_CACHE_ACCESSES];
|
randomx::SuperscalarProgram programs[RANDOMX_CACHE_ACCESSES];
|
||||||
std::vector<uint64_t> reciprocalCache;
|
std::vector<uint64_t> reciprocalCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//A pointer to a standard-layout struct object points to its initial member
|
||||||
|
static_assert(std::is_standard_layout<randomx_dataset>(), "randomx_dataset must be a standard-layout struct");
|
||||||
|
static_assert(std::is_standard_layout<randomx_cache>(), "randomx_cache must be a standard-layout struct");
|
||||||
|
|
||||||
namespace randomx {
|
namespace randomx {
|
||||||
|
|
||||||
template<class Allocator>
|
using DefaultAllocator = AlignedAllocator<CacheLineSize>;
|
||||||
struct Dataset : public randomx_dataset {
|
|
||||||
~Dataset() override;
|
|
||||||
void allocate() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
using DatasetDefault = Dataset<AlignedAllocator<CacheLineSize>>;
|
|
||||||
using DatasetLargePage = Dataset<LargePageAllocator>;
|
|
||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
struct Cache : public randomx_cache {
|
void deallocDataset(randomx_dataset* dataset) {
|
||||||
~Cache() override;
|
if (dataset->memory != nullptr)
|
||||||
void allocate() override;
|
Allocator::freeMemory(dataset->memory, DatasetSize);
|
||||||
DatasetInitFunc getInitFunc() override;
|
}
|
||||||
};
|
|
||||||
|
|
||||||
template<class Allocator>
|
template<class Allocator>
|
||||||
struct CacheWithJit : public Cache<Allocator> {
|
void deallocCache(randomx_cache* cache) {
|
||||||
using Cache<Allocator>::programs;
|
if(cache->memory != nullptr)
|
||||||
using Cache<Allocator>::reciprocalCache;
|
Allocator::freeMemory(cache->memory, CacheSize);
|
||||||
void initialize(const void *seed, size_t seedSize) override;
|
if (cache->jit != nullptr)
|
||||||
DatasetInitFunc getInitFunc() override;
|
delete cache->jit;
|
||||||
JitCompilerX86 jit;
|
}
|
||||||
};
|
|
||||||
|
|
||||||
using CacheDefault = Cache<AlignedAllocator<CacheLineSize>>;
|
|
||||||
using CacheWithJitDefault = CacheWithJit<AlignedAllocator<CacheLineSize>>;
|
|
||||||
using CacheLargePage = Cache<LargePageAllocator>;
|
|
||||||
using CacheWithJitLargePage = CacheWithJit<LargePageAllocator>;
|
|
||||||
|
|
||||||
|
void initCache(randomx_cache*, const void*, size_t);
|
||||||
|
void initCacheCompile(randomx_cache*, const void*, size_t);
|
||||||
void initDatasetItem(randomx_cache* cache, uint8_t* out, uint64_t blockNumber);
|
void initDatasetItem(randomx_cache* cache, uint8_t* out, uint64_t blockNumber);
|
||||||
void initDataset(randomx_cache* cache, uint8_t* dataset, uint32_t startBlock, uint32_t endBlock);
|
void initDataset(randomx_cache* cache, uint8_t* dataset, uint32_t startBlock, uint32_t endBlock);
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ along with RandomX. If not, see<http://www.gnu.org/licenses/>.
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <type_traits>
|
||||||
#include "blake2/endian.h"
|
#include "blake2/endian.h"
|
||||||
|
|
||||||
namespace randomx {
|
namespace randomx {
|
||||||
@ -93,10 +94,9 @@ namespace randomx {
|
|||||||
uint8_t opcode;
|
uint8_t opcode;
|
||||||
uint8_t dst;
|
uint8_t dst;
|
||||||
uint8_t src;
|
uint8_t src;
|
||||||
private:
|
|
||||||
uint8_t mod;
|
uint8_t mod;
|
||||||
uint32_t imm32;
|
uint32_t imm32;
|
||||||
|
private:
|
||||||
void print(std::ostream&) const;
|
void print(std::ostream&) const;
|
||||||
static const char* names[256];
|
static const char* names[256];
|
||||||
static InstructionFormatter engine[256];
|
static InstructionFormatter engine[256];
|
||||||
@ -136,5 +136,5 @@ namespace randomx {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(Instruction) == 8, "Invalid size of struct randomx::Instruction");
|
static_assert(sizeof(Instruction) == 8, "Invalid size of struct randomx::Instruction");
|
||||||
|
static_assert(std::is_standard_layout<Instruction>(), "randomx::Instruction must be a standard-layout struct");
|
||||||
}
|
}
|
@ -89,7 +89,7 @@ DECL(randomx_dataset_init):
|
|||||||
push r13
|
push r13
|
||||||
push r14
|
push r14
|
||||||
push r15
|
push r15
|
||||||
mov rdi, qword ptr [rdi+8] ;# after virtual method table pointer
|
mov rdi, qword ptr [rdi] ;# cache->memory
|
||||||
;# dataset in rsi
|
;# dataset in rsi
|
||||||
mov rbp, rdx ;# block index
|
mov rbp, rdx ;# block index
|
||||||
push rcx ;# max. block index
|
push rcx ;# max. block index
|
||||||
|
@ -92,7 +92,7 @@ randomx_dataset_init PROC
|
|||||||
push r13
|
push r13
|
||||||
push r14
|
push r14
|
||||||
push r15
|
push r15
|
||||||
mov rdi, qword ptr [rcx+8] ;# after virtual method table pointer
|
mov rdi, qword ptr [rcx] ;# cache->memory
|
||||||
mov rsi, rdx ;# dataset
|
mov rsi, rdx ;# dataset
|
||||||
mov rbp, r8 ;# block index
|
mov rbp, r8 ;# block index
|
||||||
push r9 ;# max. block index
|
push r9 ;# max. block index
|
||||||
|
@ -28,34 +28,48 @@ along with RandomX. If not, see<http://www.gnu.org/licenses/>.
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
randomx_cache *randomx_alloc_cache(randomx_flags flags) {
|
randomx_cache *randomx_alloc_cache(randomx_flags flags) {
|
||||||
randomx_cache *cache = nullptr;
|
randomx_cache *cache = new randomx_cache();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
switch (flags & (RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES)) {
|
switch (flags & (RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES)) {
|
||||||
case RANDOMX_FLAG_DEFAULT:
|
case RANDOMX_FLAG_DEFAULT:
|
||||||
cache = new randomx::CacheDefault();
|
cache->dealloc = &randomx::deallocCache<randomx::DefaultAllocator>;
|
||||||
|
cache->jit = nullptr;
|
||||||
|
cache->initialize = &randomx::initCache;
|
||||||
|
cache->datasetInit = &randomx::initDataset;
|
||||||
|
cache->memory = (uint8_t*)randomx::DefaultAllocator::allocMemory(randomx::CacheSize);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RANDOMX_FLAG_JIT:
|
case RANDOMX_FLAG_JIT:
|
||||||
cache = new randomx::CacheWithJitDefault();
|
cache->dealloc = &randomx::deallocCache<randomx::DefaultAllocator>;
|
||||||
|
cache->jit = new randomx::JitCompilerX86();
|
||||||
|
cache->initialize = &randomx::initCacheCompile;
|
||||||
|
cache->datasetInit = cache->jit->getDatasetInitFunc();
|
||||||
|
cache->memory = (uint8_t*)randomx::DefaultAllocator::allocMemory(randomx::CacheSize);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RANDOMX_FLAG_LARGE_PAGES:
|
case RANDOMX_FLAG_LARGE_PAGES:
|
||||||
cache = new randomx::CacheLargePage();
|
cache->dealloc = &randomx::deallocCache<randomx::LargePageAllocator>;
|
||||||
|
cache->jit = nullptr;
|
||||||
|
cache->initialize = &randomx::initCache;
|
||||||
|
cache->datasetInit = &randomx::initDataset;
|
||||||
|
cache->memory = (uint8_t*)randomx::LargePageAllocator::allocMemory(randomx::CacheSize);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES:
|
case RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES:
|
||||||
cache = new randomx::CacheWithJitLargePage();
|
cache->dealloc = &randomx::deallocCache<randomx::LargePageAllocator>;
|
||||||
|
cache->jit = new randomx::JitCompilerX86();
|
||||||
|
cache->initialize = &randomx::initCacheCompile;
|
||||||
|
cache->datasetInit = cache->jit->getDatasetInitFunc();
|
||||||
|
cache->memory = (uint8_t*)randomx::LargePageAllocator::allocMemory(randomx::CacheSize);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
UNREACHABLE;
|
UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
cache->allocate();
|
|
||||||
}
|
}
|
||||||
catch (std::exception &ex) {
|
catch (std::exception &ex) {
|
||||||
delete cache;
|
randomx_release_cache(cache);
|
||||||
cache = nullptr;
|
cache = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,27 +77,29 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void randomx_init_cache(randomx_cache *cache, const void *seed, size_t seedSize) {
|
void randomx_init_cache(randomx_cache *cache, const void *seed, size_t seedSize) {
|
||||||
cache->initialize(seed, seedSize);
|
cache->initialize(cache, seed, seedSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void randomx_release_cache(randomx_cache* cache) {
|
void randomx_release_cache(randomx_cache* cache) {
|
||||||
|
cache->dealloc(cache);
|
||||||
delete cache;
|
delete cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
randomx_dataset *randomx_alloc_dataset(randomx_flags flags) {
|
randomx_dataset *randomx_alloc_dataset(randomx_flags flags) {
|
||||||
randomx_dataset *dataset = nullptr;
|
randomx_dataset *dataset = new randomx_dataset();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (flags & RANDOMX_FLAG_LARGE_PAGES) {
|
if (flags & RANDOMX_FLAG_LARGE_PAGES) {
|
||||||
dataset = new randomx::DatasetLargePage();
|
dataset->dealloc = &randomx::deallocDataset<randomx::LargePageAllocator>;
|
||||||
|
dataset->memory = (uint8_t*)randomx::LargePageAllocator::allocMemory(randomx::DatasetSize);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dataset = new randomx::DatasetDefault();
|
dataset->dealloc = &randomx::deallocDataset<randomx::DefaultAllocator>;
|
||||||
|
dataset->memory = (uint8_t*)randomx::DefaultAllocator::allocMemory(randomx::DatasetSize);
|
||||||
}
|
}
|
||||||
dataset->allocate();
|
|
||||||
}
|
}
|
||||||
catch (std::exception &ex) {
|
catch (std::exception &ex) {
|
||||||
delete dataset;
|
randomx_release_dataset(dataset);
|
||||||
dataset = nullptr;
|
dataset = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,8 +111,7 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void randomx_init_dataset(randomx_dataset *dataset, randomx_cache *cache, unsigned long startItem, unsigned long itemCount) {
|
void randomx_init_dataset(randomx_dataset *dataset, randomx_cache *cache, unsigned long startItem, unsigned long itemCount) {
|
||||||
randomx::DatasetInitFunc dsfunc = cache->getInitFunc();
|
cache->datasetInit(cache, dataset->memory + startItem * randomx::CacheLineSize, startItem, startItem + itemCount);
|
||||||
dsfunc(cache, dataset->memory + startItem * randomx::CacheLineSize, startItem, startItem + itemCount);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *randomx_get_dataset_memory(randomx_dataset *dataset) {
|
void *randomx_get_dataset_memory(randomx_dataset *dataset) {
|
||||||
@ -104,6 +119,7 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void randomx_release_dataset(randomx_dataset *dataset) {
|
void randomx_release_dataset(randomx_dataset *dataset) {
|
||||||
|
dataset->dealloc(dataset);
|
||||||
delete dataset;
|
delete dataset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +46,10 @@ namespace randomx {
|
|||||||
void setAddressRegister(uint32_t val) {
|
void setAddressRegister(uint32_t val) {
|
||||||
addrReg = val;
|
addrReg = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Instruction programBuffer[RANDOMX_SUPERSCALAR_MAX_SIZE];
|
||||||
|
uint32_t size;
|
||||||
|
int addrReg;
|
||||||
double ipc;
|
double ipc;
|
||||||
int codeSize;
|
int codeSize;
|
||||||
int macroOps;
|
int macroOps;
|
||||||
@ -62,9 +66,6 @@ namespace randomx {
|
|||||||
os << instr;
|
os << instr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instruction programBuffer[RANDOMX_SUPERSCALAR_MAX_SIZE];
|
|
||||||
uint32_t size;
|
|
||||||
int addrReg;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
@ -165,15 +165,13 @@ int main(int argc, char** argv) {
|
|||||||
Stopwatch sw(true);
|
Stopwatch sw(true);
|
||||||
cache = randomx_alloc_cache(flags);
|
cache = randomx_alloc_cache(flags);
|
||||||
if (cache == nullptr) {
|
if (cache == nullptr) {
|
||||||
std::cout << "ERROR: Cache allocation failed" << std::endl;
|
throw std::runtime_error("Cache allocation failed");
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
randomx_init_cache(cache, &seed, sizeof(seed));
|
randomx_init_cache(cache, &seed, sizeof(seed));
|
||||||
if (miningMode) {
|
if (miningMode) {
|
||||||
dataset = randomx_alloc_dataset(flags);
|
dataset = randomx_alloc_dataset(flags);
|
||||||
if (dataset == nullptr) {
|
if (dataset == nullptr) {
|
||||||
std::cout << "ERROR: Dataset allocation failed" << std::endl;
|
throw std::runtime_error("Dataset allocation failed");
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
uint32_t datasetItemCount = randomx_dataset_item_count();
|
uint32_t datasetItemCount = randomx_dataset_item_count();
|
||||||
if (initThreadCount > 1) {
|
if (initThreadCount > 1) {
|
||||||
@ -200,8 +198,7 @@ int main(int argc, char** argv) {
|
|||||||
for (int i = 0; i < threadCount; ++i) {
|
for (int i = 0; i < threadCount; ++i) {
|
||||||
randomx_vm *vm = randomx_create_vm(flags, cache, dataset);
|
randomx_vm *vm = randomx_create_vm(flags, cache, dataset);
|
||||||
if (vm == nullptr) {
|
if (vm == nullptr) {
|
||||||
std::cout << "ERROR: Unsupported virtual machine options" << std::endl;
|
throw std::runtime_error("Unsupported virtual machine options");
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
vms.push_back(vm);
|
vms.push_back(vm);
|
||||||
}
|
}
|
||||||
@ -221,7 +218,14 @@ int main(int argc, char** argv) {
|
|||||||
else {
|
else {
|
||||||
mine(vms[0], std::ref(atomicNonce), std::ref(result), noncesCount, 0);
|
mine(vms[0], std::ref(atomicNonce), std::ref(result), noncesCount, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
double elapsed = sw.getElapsed();
|
double elapsed = sw.getElapsed();
|
||||||
|
for (unsigned i = 0; i < vms.size(); ++i)
|
||||||
|
randomx_destroy_vm(vms[i]);
|
||||||
|
if (miningMode)
|
||||||
|
randomx_release_dataset(dataset);
|
||||||
|
else
|
||||||
|
randomx_release_cache(cache);
|
||||||
std::cout << "Calculated result: ";
|
std::cout << "Calculated result: ";
|
||||||
result.print(std::cout);
|
result.print(std::cout);
|
||||||
if (noncesCount == 1000 && seedValue == 0)
|
if (noncesCount == 1000 && seedValue == 0)
|
||||||
|
@ -103,7 +103,7 @@ namespace randomx {
|
|||||||
|
|
||||||
template<class Allocator, bool softAes>
|
template<class Allocator, bool softAes>
|
||||||
void VmBase<Allocator, softAes>::allocate() {
|
void VmBase<Allocator, softAes>::allocate() {
|
||||||
if (mem.memory == nullptr)
|
if (datasetPtr == nullptr)
|
||||||
throw std::invalid_argument("Cache/Dataset not set");
|
throw std::invalid_argument("Cache/Dataset not set");
|
||||||
if (!softAes) { //if hardware AES is not supported, it's better to fail now than to return a ticking bomb
|
if (!softAes) { //if hardware AES is not supported, it's better to fail now than to return a ticking bomb
|
||||||
__m128i tmp = _mm_load_si128((const __m128i*)&aesDummy);
|
__m128i tmp = _mm_load_si128((const __m128i*)&aesDummy);
|
||||||
|
@ -44,7 +44,10 @@ protected:
|
|||||||
alignas(16) randomx::ProgramConfiguration config;
|
alignas(16) randomx::ProgramConfiguration config;
|
||||||
randomx::MemoryRegisters mem;
|
randomx::MemoryRegisters mem;
|
||||||
uint8_t* scratchpad;
|
uint8_t* scratchpad;
|
||||||
uint8_t* datasetBasePtr;
|
union {
|
||||||
|
randomx_cache* cachePtr = nullptr;
|
||||||
|
randomx_dataset* datasetPtr;
|
||||||
|
};
|
||||||
uint32_t datasetOffset;
|
uint32_t datasetOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -27,8 +27,7 @@ namespace randomx {
|
|||||||
|
|
||||||
template<class Allocator, bool softAes>
|
template<class Allocator, bool softAes>
|
||||||
void CompiledVm<Allocator, softAes>::setDataset(randomx_dataset* dataset) {
|
void CompiledVm<Allocator, softAes>::setDataset(randomx_dataset* dataset) {
|
||||||
mem.memory = dataset->memory;
|
datasetPtr = dataset;
|
||||||
datasetBasePtr = dataset->memory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Allocator, bool softAes>
|
template<class Allocator, bool softAes>
|
||||||
@ -36,7 +35,7 @@ namespace randomx {
|
|||||||
VmBase<Allocator, softAes>::generateProgram(seed);
|
VmBase<Allocator, softAes>::generateProgram(seed);
|
||||||
randomx_vm::initialize();
|
randomx_vm::initialize();
|
||||||
compiler.generateProgram(program, config);
|
compiler.generateProgram(program, config);
|
||||||
mem.memory = datasetBasePtr + datasetOffset;
|
mem.memory = datasetPtr->memory + datasetOffset;
|
||||||
execute();
|
execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ namespace randomx {
|
|||||||
using VmBase<Allocator, softAes>::config;
|
using VmBase<Allocator, softAes>::config;
|
||||||
using VmBase<Allocator, softAes>::reg;
|
using VmBase<Allocator, softAes>::reg;
|
||||||
using VmBase<Allocator, softAes>::scratchpad;
|
using VmBase<Allocator, softAes>::scratchpad;
|
||||||
using VmBase<Allocator, softAes>::datasetBasePtr;
|
using VmBase<Allocator, softAes>::datasetPtr;
|
||||||
using VmBase<Allocator, softAes>::datasetOffset;
|
using VmBase<Allocator, softAes>::datasetOffset;
|
||||||
protected:
|
protected:
|
||||||
void execute();
|
void execute();
|
||||||
|
@ -25,6 +25,7 @@ namespace randomx {
|
|||||||
|
|
||||||
template<class Allocator, bool softAes>
|
template<class Allocator, bool softAes>
|
||||||
void CompiledLightVm<Allocator, softAes>::setCache(randomx_cache* cache) {
|
void CompiledLightVm<Allocator, softAes>::setCache(randomx_cache* cache) {
|
||||||
|
cachePtr = cache;
|
||||||
mem.memory = cache->memory;
|
mem.memory = cache->memory;
|
||||||
compiler.generateSuperscalarHash(cache->programs, cache->reciprocalCache);
|
compiler.generateSuperscalarHash(cache->programs, cache->reciprocalCache);
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ namespace randomx {
|
|||||||
using CompiledVm<Allocator, softAes>::compiler;
|
using CompiledVm<Allocator, softAes>::compiler;
|
||||||
using CompiledVm<Allocator, softAes>::program;
|
using CompiledVm<Allocator, softAes>::program;
|
||||||
using CompiledVm<Allocator, softAes>::config;
|
using CompiledVm<Allocator, softAes>::config;
|
||||||
|
using CompiledVm<Allocator, softAes>::cachePtr;
|
||||||
using CompiledVm<Allocator, softAes>::datasetOffset;
|
using CompiledVm<Allocator, softAes>::datasetOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ namespace randomx {
|
|||||||
|
|
||||||
template<class Allocator, bool softAes>
|
template<class Allocator, bool softAes>
|
||||||
void InterpretedVm<Allocator, softAes>::setDataset(randomx_dataset* dataset) {
|
void InterpretedVm<Allocator, softAes>::setDataset(randomx_dataset* dataset) {
|
||||||
|
datasetPtr = dataset;
|
||||||
mem.memory = dataset->memory;
|
mem.memory = dataset->memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ namespace randomx {
|
|||||||
using VmBase<Allocator, softAes>::program;
|
using VmBase<Allocator, softAes>::program;
|
||||||
using VmBase<Allocator, softAes>::config;
|
using VmBase<Allocator, softAes>::config;
|
||||||
using VmBase<Allocator, softAes>::reg;
|
using VmBase<Allocator, softAes>::reg;
|
||||||
using VmBase<Allocator, softAes>::datasetBasePtr;
|
using VmBase<Allocator, softAes>::datasetPtr;
|
||||||
using VmBase<Allocator, softAes>::datasetOffset;
|
using VmBase<Allocator, softAes>::datasetOffset;
|
||||||
void* operator new(size_t size) {
|
void* operator new(size_t size) {
|
||||||
void* ptr = AlignedAllocator<CacheLineSize>::allocMemory(size);
|
void* ptr = AlignedAllocator<CacheLineSize>::allocMemory(size);
|
||||||
|
@ -24,8 +24,8 @@ namespace randomx {
|
|||||||
|
|
||||||
template<class Allocator, bool softAes>
|
template<class Allocator, bool softAes>
|
||||||
void InterpretedLightVm<Allocator, softAes>::setCache(randomx_cache* cache) {
|
void InterpretedLightVm<Allocator, softAes>::setCache(randomx_cache* cache) {
|
||||||
mem.memory = cache->memory;
|
|
||||||
cachePtr = cache;
|
cachePtr = cache;
|
||||||
|
mem.memory = cache->memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Allocator, bool softAes>
|
template<class Allocator, bool softAes>
|
||||||
|
@ -28,6 +28,7 @@ namespace randomx {
|
|||||||
class InterpretedLightVm : public InterpretedVm<Allocator, softAes> {
|
class InterpretedLightVm : public InterpretedVm<Allocator, softAes> {
|
||||||
public:
|
public:
|
||||||
using VmBase<Allocator, softAes>::mem;
|
using VmBase<Allocator, softAes>::mem;
|
||||||
|
using VmBase<Allocator, softAes>::cachePtr;
|
||||||
void* operator new(size_t size) {
|
void* operator new(size_t size) {
|
||||||
void* ptr = AlignedAllocator<CacheLineSize>::allocMemory(size);
|
void* ptr = AlignedAllocator<CacheLineSize>::allocMemory(size);
|
||||||
if (ptr == nullptr)
|
if (ptr == nullptr)
|
||||||
@ -41,8 +42,6 @@ namespace randomx {
|
|||||||
void setCache(randomx_cache* cache) override;
|
void setCache(randomx_cache* cache) override;
|
||||||
protected:
|
protected:
|
||||||
void datasetRead(uint32_t address, int_reg_t(&r)[8]) override;
|
void datasetRead(uint32_t address, int_reg_t(&r)[8]) override;
|
||||||
private:
|
|
||||||
randomx_cache* cachePtr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using InterpretedLightVmDefault = InterpretedLightVm<AlignedAllocator<CacheLineSize>, true>;
|
using InterpretedLightVmDefault = InterpretedLightVm<AlignedAllocator<CacheLineSize>, true>;
|
||||||
|
Loading…
Reference in New Issue
Block a user