randomx_cache and randomx_dataset changed to standard-layout structs

This commit is contained in:
tevador 2019-04-28 12:44:28 +02:00
parent fd7186f873
commit 22a3aa8d79
19 changed files with 155 additions and 173 deletions

View File

@ -113,6 +113,10 @@ namespace randomx {
typedef void(*DatasetReadFunc)(addr_t, MemoryRegisters&, int_reg_t(&reg)[RegistersCount]); typedef void(*DatasetReadFunc)(addr_t, MemoryRegisters&, int_reg_t(&reg)[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);

View File

@ -40,126 +40,84 @@ 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 {
uint32_t memory_blocks, segment_length;
argon2_instance_t instance;
argon2_context context;
context.out = nullptr; void initCache(randomx_cache* cache, const void* seed, size_t seedSize) {
context.outlen = 0; uint32_t memory_blocks, segment_length;
context.pwd = CONST_CAST(uint8_t *)seed; argon2_instance_t instance;
context.pwdlen = (uint32_t)seedSize; argon2_context context;
context.salt = CONST_CAST(uint8_t *)RANDOMX_ARGON_SALT;
context.saltlen = (uint32_t)randomx::ArgonSaltSize;
context.secret = NULL;
context.secretlen = 0;
context.ad = NULL;
context.adlen = 0;
context.t_cost = RANDOMX_ARGON_ITERATIONS;
context.m_cost = RANDOMX_ARGON_MEMORY;
context.lanes = RANDOMX_ARGON_LANES;
context.threads = 1;
context.allocate_cbk = NULL;
context.free_cbk = NULL;
context.flags = ARGON2_DEFAULT_FLAGS;
context.version = ARGON2_VERSION_NUMBER;
/* 2. Align memory size */ context.out = nullptr;
/* Minimum memory_blocks = 8L blocks, where L is the number of lanes */ context.outlen = 0;
memory_blocks = context.m_cost; context.pwd = CONST_CAST(uint8_t *)seed;
context.pwdlen = (uint32_t)seedSize;
context.salt = CONST_CAST(uint8_t *)RANDOMX_ARGON_SALT;
context.saltlen = (uint32_t)randomx::ArgonSaltSize;
context.secret = NULL;
context.secretlen = 0;
context.ad = NULL;
context.adlen = 0;
context.t_cost = RANDOMX_ARGON_ITERATIONS;
context.m_cost = RANDOMX_ARGON_MEMORY;
context.lanes = RANDOMX_ARGON_LANES;
context.threads = 1;
context.allocate_cbk = NULL;
context.free_cbk = NULL;
context.flags = ARGON2_DEFAULT_FLAGS;
context.version = ARGON2_VERSION_NUMBER;
segment_length = memory_blocks / (context.lanes * ARGON2_SYNC_POINTS); /* 2. Align memory size */
/* Minimum memory_blocks = 8L blocks, where L is the number of lanes */
memory_blocks = context.m_cost;
instance.version = context.version; segment_length = memory_blocks / (context.lanes * ARGON2_SYNC_POINTS);
instance.memory = NULL;
instance.passes = context.t_cost;
instance.memory_blocks = memory_blocks;
instance.segment_length = segment_length;
instance.lane_length = segment_length * ARGON2_SYNC_POINTS;
instance.lanes = context.lanes;
instance.threads = context.threads;
instance.type = Argon2_d;
instance.memory = (block*)memory;
if (instance.threads > instance.lanes) { instance.version = context.version;
instance.threads = instance.lanes; instance.memory = NULL;
} instance.passes = context.t_cost;
instance.memory_blocks = memory_blocks;
instance.segment_length = segment_length;
instance.lane_length = segment_length * ARGON2_SYNC_POINTS;
instance.lanes = context.lanes;
instance.threads = context.threads;
instance.type = Argon2_d;
instance.memory = (block*)cache->memory;
/* 3. Initialization: Hashing inputs, allocating memory, filling first if (instance.threads > instance.lanes) {
* blocks instance.threads = instance.lanes;
*/ }
argon_initialize(&instance, &context);
fill_memory_blocks(&instance); /* 3. Initialization: Hashing inputs, allocating memory, filling first
* blocks
*/
argon_initialize(&instance, &context);
reciprocalCache.clear(); fill_memory_blocks(&instance);
randomx::Blake2Generator gen(seed, seedSize);
for (int i = 0; i < RANDOMX_CACHE_ACCESSES; ++i) { cache->reciprocalCache.clear();
randomx::generateSuperscalar(programs[i], gen); randomx::Blake2Generator gen(seed, seedSize);
for (unsigned j = 0; j < programs[i].getSize(); ++j) { for (int i = 0; i < RANDOMX_CACHE_ACCESSES; ++i) {
auto& instr = programs[i](j); randomx::generateSuperscalar(cache->programs[i], gen);
if (instr.opcode == randomx::SuperscalarInstructionType::IMUL_RCP) { for (unsigned j = 0; j < cache->programs[i].getSize(); ++j) {
auto rcp = randomx_reciprocal(instr.getImm32()); auto& instr = cache->programs[i](j);
instr.setImm32(reciprocalCache.size()); if (instr.opcode == randomx::SuperscalarInstructionType::IMUL_RCP) {
reciprocalCache.push_back(rcp); auto rcp = randomx_reciprocal(instr.getImm32());
instr.setImm32(cache->reciprocalCache.size());
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;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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