mirror of
https://git.wownero.com/wownero/RandomWOW.git
synced 2024-08-15 00:23:14 +00:00
randomx_cache and randomx_dataset changed to standard-layout structs
This commit is contained in:
parent
fd7186f873
commit
22a3aa8d79
19 changed files with 155 additions and 173 deletions
|
@ -113,6 +113,10 @@ namespace randomx {
|
|||
typedef void(*DatasetReadFunc)(addr_t, MemoryRegisters&, int_reg_t(®)[RegistersCount]);
|
||||
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(*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);
|
||||
|
|
164
src/dataset.cpp
164
src/dataset.cpp
|
@ -40,126 +40,84 @@ along with RandomX. If not, see<http://www.gnu.org/licenses/>.
|
|||
#include "argon2.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(ARGON2_BLOCK_SIZE == randomx::ArgonBlockSize, "Unpexpected value of ARGON2_BLOCK_SIZE");
|
||||
|
||||
void randomx_cache::initialize(const void *seed, size_t seedSize) {
|
||||
uint32_t memory_blocks, segment_length;
|
||||
argon2_instance_t instance;
|
||||
argon2_context context;
|
||||
namespace randomx {
|
||||
|
||||
context.out = nullptr;
|
||||
context.outlen = 0;
|
||||
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;
|
||||
void initCache(randomx_cache* cache, const void* seed, size_t seedSize) {
|
||||
uint32_t memory_blocks, segment_length;
|
||||
argon2_instance_t instance;
|
||||
argon2_context context;
|
||||
|
||||
/* 2. Align memory size */
|
||||
/* Minimum memory_blocks = 8L blocks, where L is the number of lanes */
|
||||
memory_blocks = context.m_cost;
|
||||
context.out = nullptr;
|
||||
context.outlen = 0;
|
||||
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;
|
||||
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;
|
||||
segment_length = memory_blocks / (context.lanes * ARGON2_SYNC_POINTS);
|
||||
|
||||
if (instance.threads > instance.lanes) {
|
||||
instance.threads = instance.lanes;
|
||||
}
|
||||
instance.version = context.version;
|
||||
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
|
||||
* blocks
|
||||
*/
|
||||
argon_initialize(&instance, &context);
|
||||
if (instance.threads > instance.lanes) {
|
||||
instance.threads = instance.lanes;
|
||||
}
|
||||
|
||||
fill_memory_blocks(&instance);
|
||||
/* 3. Initialization: Hashing inputs, allocating memory, filling first
|
||||
* blocks
|
||||
*/
|
||||
argon_initialize(&instance, &context);
|
||||
|
||||
reciprocalCache.clear();
|
||||
randomx::Blake2Generator gen(seed, seedSize);
|
||||
for (int i = 0; i < RANDOMX_CACHE_ACCESSES; ++i) {
|
||||
randomx::generateSuperscalar(programs[i], gen);
|
||||
for (unsigned j = 0; j < programs[i].getSize(); ++j) {
|
||||
auto& instr = programs[i](j);
|
||||
if (instr.opcode == randomx::SuperscalarInstructionType::IMUL_RCP) {
|
||||
auto rcp = randomx_reciprocal(instr.getImm32());
|
||||
instr.setImm32(reciprocalCache.size());
|
||||
reciprocalCache.push_back(rcp);
|
||||
fill_memory_blocks(&instance);
|
||||
|
||||
cache->reciprocalCache.clear();
|
||||
randomx::Blake2Generator gen(seed, seedSize);
|
||||
for (int i = 0; i < RANDOMX_CACHE_ACCESSES; ++i) {
|
||||
randomx::generateSuperscalar(cache->programs[i], gen);
|
||||
for (unsigned j = 0; j < cache->programs[i].getSize(); ++j) {
|
||||
auto& instr = cache->programs[i](j);
|
||||
if (instr.opcode == randomx::SuperscalarInstructionType::IMUL_RCP) {
|
||||
auto rcp = randomx_reciprocal(instr.getImm32());
|
||||
instr.setImm32(cache->reciprocalCache.size());
|
||||
cache->reciprocalCache.push_back(rcp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace randomx {
|
||||
|
||||
template<class Allocator>
|
||||
void Dataset<Allocator>::allocate() {
|
||||
memory = (uint8_t*)Allocator::allocMemory(DatasetSize);
|
||||
void initCacheCompile(randomx_cache* cache, const void* seed, size_t seedSize) {
|
||||
initCache(cache, seed, seedSize);
|
||||
cache->jit->generateSuperscalarHash(cache->programs, cache->reciprocalCache);
|
||||
cache->jit->generateDatasetInitCode();
|
||||
}
|
||||
|
||||
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 superscalarAdd1 = 9298411001130361340ULL;
|
||||
constexpr uint64_t superscalarAdd2 = 12065312585734608966ULL;
|
||||
|
|
|
@ -21,6 +21,7 @@ along with RandomX. If not, see<http://www.gnu.org/licenses/>.
|
|||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <type_traits>
|
||||
#include "common.hpp"
|
||||
#include "superscalar_program.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 */
|
||||
struct randomx_dataset {
|
||||
virtual ~randomx_dataset() = 0;
|
||||
virtual void allocate() = 0;
|
||||
uint8_t* memory = nullptr;
|
||||
randomx::DatasetDeallocFunc dealloc;
|
||||
};
|
||||
|
||||
/* Global scope for C binding */
|
||||
struct randomx_cache : public randomx_dataset {
|
||||
virtual randomx::DatasetInitFunc getInitFunc() = 0;
|
||||
virtual void initialize(const void *seed, size_t seedSize);
|
||||
struct randomx_cache {
|
||||
uint8_t* memory = nullptr;
|
||||
randomx::CacheDeallocFunc dealloc;
|
||||
randomx::JitCompilerX86* jit;
|
||||
randomx::CacheInitializeFunc initialize;
|
||||
randomx::DatasetInitFunc datasetInit;
|
||||
randomx::SuperscalarProgram programs[RANDOMX_CACHE_ACCESSES];
|
||||
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 {
|
||||
|
||||
template<class Allocator>
|
||||
struct Dataset : public randomx_dataset {
|
||||
~Dataset() override;
|
||||
void allocate() override;
|
||||
};
|
||||
|
||||
using DatasetDefault = Dataset<AlignedAllocator<CacheLineSize>>;
|
||||
using DatasetLargePage = Dataset<LargePageAllocator>;
|
||||
using DefaultAllocator = AlignedAllocator<CacheLineSize>;
|
||||
|
||||
template<class Allocator>
|
||||
struct Cache : public randomx_cache {
|
||||
~Cache() override;
|
||||
void allocate() override;
|
||||
DatasetInitFunc getInitFunc() override;
|
||||
};
|
||||
void deallocDataset(randomx_dataset* dataset) {
|
||||
if (dataset->memory != nullptr)
|
||||
Allocator::freeMemory(dataset->memory, DatasetSize);
|
||||
}
|
||||
|
||||
template<class Allocator>
|
||||
struct CacheWithJit : public Cache<Allocator> {
|
||||
using Cache<Allocator>::programs;
|
||||
using Cache<Allocator>::reciprocalCache;
|
||||
void initialize(const void *seed, size_t seedSize) override;
|
||||
DatasetInitFunc getInitFunc() override;
|
||||
JitCompilerX86 jit;
|
||||
};
|
||||
|
||||
using CacheDefault = Cache<AlignedAllocator<CacheLineSize>>;
|
||||
using CacheWithJitDefault = CacheWithJit<AlignedAllocator<CacheLineSize>>;
|
||||
using CacheLargePage = Cache<LargePageAllocator>;
|
||||
using CacheWithJitLargePage = CacheWithJit<LargePageAllocator>;
|
||||
void deallocCache(randomx_cache* cache) {
|
||||
if(cache->memory != nullptr)
|
||||
Allocator::freeMemory(cache->memory, CacheSize);
|
||||
if (cache->jit != nullptr)
|
||||
delete cache->jit;
|
||||
}
|
||||
|
||||
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 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 <iostream>
|
||||
#include <type_traits>
|
||||
#include "blake2/endian.h"
|
||||
|
||||
namespace randomx {
|
||||
|
@ -93,10 +94,9 @@ namespace randomx {
|
|||
uint8_t opcode;
|
||||
uint8_t dst;
|
||||
uint8_t src;
|
||||
private:
|
||||
uint8_t mod;
|
||||
uint32_t imm32;
|
||||
|
||||
private:
|
||||
void print(std::ostream&) const;
|
||||
static const char* names[256];
|
||||
static InstructionFormatter engine[256];
|
||||
|
@ -136,5 +136,5 @@ namespace randomx {
|
|||
};
|
||||
|
||||
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 r14
|
||||
push r15
|
||||
mov rdi, qword ptr [rdi+8] ;# after virtual method table pointer
|
||||
mov rdi, qword ptr [rdi] ;# cache->memory
|
||||
;# dataset in rsi
|
||||
mov rbp, rdx ;# block index
|
||||
push rcx ;# max. block index
|
||||
|
|
|
@ -92,7 +92,7 @@ randomx_dataset_init PROC
|
|||
push r13
|
||||
push r14
|
||||
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 rbp, r8 ;# block index
|
||||
push r9 ;# max. block index
|
||||
|
|
|
@ -28,34 +28,48 @@ along with RandomX. If not, see<http://www.gnu.org/licenses/>.
|
|||
extern "C" {
|
||||
|
||||
randomx_cache *randomx_alloc_cache(randomx_flags flags) {
|
||||
randomx_cache *cache = nullptr;
|
||||
randomx_cache *cache = new randomx_cache();
|
||||
|
||||
try {
|
||||
switch (flags & (RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES)) {
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
default:
|
||||
UNREACHABLE;
|
||||
}
|
||||
|
||||
cache->allocate();
|
||||
}
|
||||
catch (std::exception &ex) {
|
||||
delete cache;
|
||||
randomx_release_cache(cache);
|
||||
cache = nullptr;
|
||||
}
|
||||
|
||||
|
@ -63,27 +77,29 @@ extern "C" {
|
|||
}
|
||||
|
||||
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) {
|
||||
cache->dealloc(cache);
|
||||
delete cache;
|
||||
}
|
||||
|
||||
randomx_dataset *randomx_alloc_dataset(randomx_flags flags) {
|
||||
randomx_dataset *dataset = nullptr;
|
||||
randomx_dataset *dataset = new randomx_dataset();
|
||||
|
||||
try {
|
||||
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 {
|
||||
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) {
|
||||
delete dataset;
|
||||
randomx_release_dataset(dataset);
|
||||
dataset = nullptr;
|
||||
}
|
||||
|
||||
|
@ -95,8 +111,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
void randomx_init_dataset(randomx_dataset *dataset, randomx_cache *cache, unsigned long startItem, unsigned long itemCount) {
|
||||
randomx::DatasetInitFunc dsfunc = cache->getInitFunc();
|
||||
dsfunc(cache, dataset->memory + startItem * randomx::CacheLineSize, startItem, startItem + itemCount);
|
||||
cache->datasetInit(cache, dataset->memory + startItem * randomx::CacheLineSize, startItem, startItem + itemCount);
|
||||
}
|
||||
|
||||
void *randomx_get_dataset_memory(randomx_dataset *dataset) {
|
||||
|
@ -104,6 +119,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
void randomx_release_dataset(randomx_dataset *dataset) {
|
||||
dataset->dealloc(dataset);
|
||||
delete dataset;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,10 @@ namespace randomx {
|
|||
void setAddressRegister(uint32_t val) {
|
||||
addrReg = val;
|
||||
}
|
||||
|
||||
Instruction programBuffer[RANDOMX_SUPERSCALAR_MAX_SIZE];
|
||||
uint32_t size;
|
||||
int addrReg;
|
||||
double ipc;
|
||||
int codeSize;
|
||||
int macroOps;
|
||||
|
@ -62,9 +66,6 @@ namespace randomx {
|
|||
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);
|
||||
cache = randomx_alloc_cache(flags);
|
||||
if (cache == nullptr) {
|
||||
std::cout << "ERROR: Cache allocation failed" << std::endl;
|
||||
return 1;
|
||||
throw std::runtime_error("Cache allocation failed");
|
||||
}
|
||||
randomx_init_cache(cache, &seed, sizeof(seed));
|
||||
if (miningMode) {
|
||||
dataset = randomx_alloc_dataset(flags);
|
||||
if (dataset == nullptr) {
|
||||
std::cout << "ERROR: Dataset allocation failed" << std::endl;
|
||||
return 1;
|
||||
throw std::runtime_error("Dataset allocation failed");
|
||||
}
|
||||
uint32_t datasetItemCount = randomx_dataset_item_count();
|
||||
if (initThreadCount > 1) {
|
||||
|
@ -200,8 +198,7 @@ int main(int argc, char** argv) {
|
|||
for (int i = 0; i < threadCount; ++i) {
|
||||
randomx_vm *vm = randomx_create_vm(flags, cache, dataset);
|
||||
if (vm == nullptr) {
|
||||
std::cout << "ERROR: Unsupported virtual machine options" << std::endl;
|
||||
return 1;
|
||||
throw std::runtime_error("Unsupported virtual machine options");
|
||||
}
|
||||
vms.push_back(vm);
|
||||
}
|
||||
|
@ -221,7 +218,14 @@ int main(int argc, char** argv) {
|
|||
else {
|
||||
mine(vms[0], std::ref(atomicNonce), std::ref(result), noncesCount, 0);
|
||||
}
|
||||
|
||||
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: ";
|
||||
result.print(std::cout);
|
||||
if (noncesCount == 1000 && seedValue == 0)
|
||||
|
|
|
@ -103,7 +103,7 @@ namespace randomx {
|
|||
|
||||
template<class Allocator, bool softAes>
|
||||
void VmBase<Allocator, softAes>::allocate() {
|
||||
if (mem.memory == nullptr)
|
||||
if (datasetPtr == nullptr)
|
||||
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
|
||||
__m128i tmp = _mm_load_si128((const __m128i*)&aesDummy);
|
||||
|
|
|
@ -44,7 +44,10 @@ protected:
|
|||
alignas(16) randomx::ProgramConfiguration config;
|
||||
randomx::MemoryRegisters mem;
|
||||
uint8_t* scratchpad;
|
||||
uint8_t* datasetBasePtr;
|
||||
union {
|
||||
randomx_cache* cachePtr = nullptr;
|
||||
randomx_dataset* datasetPtr;
|
||||
};
|
||||
uint32_t datasetOffset;
|
||||
};
|
||||
|
||||
|
|
|
@ -27,8 +27,7 @@ namespace randomx {
|
|||
|
||||
template<class Allocator, bool softAes>
|
||||
void CompiledVm<Allocator, softAes>::setDataset(randomx_dataset* dataset) {
|
||||
mem.memory = dataset->memory;
|
||||
datasetBasePtr = dataset->memory;
|
||||
datasetPtr = dataset;
|
||||
}
|
||||
|
||||
template<class Allocator, bool softAes>
|
||||
|
@ -36,7 +35,7 @@ namespace randomx {
|
|||
VmBase<Allocator, softAes>::generateProgram(seed);
|
||||
randomx_vm::initialize();
|
||||
compiler.generateProgram(program, config);
|
||||
mem.memory = datasetBasePtr + datasetOffset;
|
||||
mem.memory = datasetPtr->memory + datasetOffset;
|
||||
execute();
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace randomx {
|
|||
using VmBase<Allocator, softAes>::config;
|
||||
using VmBase<Allocator, softAes>::reg;
|
||||
using VmBase<Allocator, softAes>::scratchpad;
|
||||
using VmBase<Allocator, softAes>::datasetBasePtr;
|
||||
using VmBase<Allocator, softAes>::datasetPtr;
|
||||
using VmBase<Allocator, softAes>::datasetOffset;
|
||||
protected:
|
||||
void execute();
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace randomx {
|
|||
|
||||
template<class Allocator, bool softAes>
|
||||
void CompiledLightVm<Allocator, softAes>::setCache(randomx_cache* cache) {
|
||||
cachePtr = cache;
|
||||
mem.memory = cache->memory;
|
||||
compiler.generateSuperscalarHash(cache->programs, cache->reciprocalCache);
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ namespace randomx {
|
|||
using CompiledVm<Allocator, softAes>::compiler;
|
||||
using CompiledVm<Allocator, softAes>::program;
|
||||
using CompiledVm<Allocator, softAes>::config;
|
||||
using CompiledVm<Allocator, softAes>::cachePtr;
|
||||
using CompiledVm<Allocator, softAes>::datasetOffset;
|
||||
};
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ namespace randomx {
|
|||
|
||||
template<class Allocator, bool softAes>
|
||||
void InterpretedVm<Allocator, softAes>::setDataset(randomx_dataset* dataset) {
|
||||
datasetPtr = dataset;
|
||||
mem.memory = dataset->memory;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace randomx {
|
|||
using VmBase<Allocator, softAes>::program;
|
||||
using VmBase<Allocator, softAes>::config;
|
||||
using VmBase<Allocator, softAes>::reg;
|
||||
using VmBase<Allocator, softAes>::datasetBasePtr;
|
||||
using VmBase<Allocator, softAes>::datasetPtr;
|
||||
using VmBase<Allocator, softAes>::datasetOffset;
|
||||
void* operator new(size_t size) {
|
||||
void* ptr = AlignedAllocator<CacheLineSize>::allocMemory(size);
|
||||
|
|
|
@ -24,8 +24,8 @@ namespace randomx {
|
|||
|
||||
template<class Allocator, bool softAes>
|
||||
void InterpretedLightVm<Allocator, softAes>::setCache(randomx_cache* cache) {
|
||||
mem.memory = cache->memory;
|
||||
cachePtr = cache;
|
||||
mem.memory = cache->memory;
|
||||
}
|
||||
|
||||
template<class Allocator, bool softAes>
|
||||
|
|
|
@ -28,6 +28,7 @@ namespace randomx {
|
|||
class InterpretedLightVm : public InterpretedVm<Allocator, softAes> {
|
||||
public:
|
||||
using VmBase<Allocator, softAes>::mem;
|
||||
using VmBase<Allocator, softAes>::cachePtr;
|
||||
void* operator new(size_t size) {
|
||||
void* ptr = AlignedAllocator<CacheLineSize>::allocMemory(size);
|
||||
if (ptr == nullptr)
|
||||
|
@ -41,8 +42,6 @@ namespace randomx {
|
|||
void setCache(randomx_cache* cache) override;
|
||||
protected:
|
||||
void datasetRead(uint32_t address, int_reg_t(&r)[8]) override;
|
||||
private:
|
||||
randomx_cache* cachePtr;
|
||||
};
|
||||
|
||||
using InterpretedLightVmDefault = InterpretedLightVm<AlignedAllocator<CacheLineSize>, true>;
|
||||
|
|
Loading…
Reference in a new issue