mirror of https://github.com/tevador/RandomX
parent
67046a9f38
commit
296e77eebc
@ -1,82 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2018 tevador
|
|
||||||
|
|
||||||
This file is part of RandomX.
|
|
||||||
|
|
||||||
RandomX 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.
|
|
||||||
|
|
||||||
RandomX 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 RandomX. If not, see<http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include "Cache.hpp"
|
|
||||||
#include "argon2.h"
|
|
||||||
#include "argon2_core.h"
|
|
||||||
|
|
||||||
namespace RandomX {
|
|
||||||
|
|
||||||
static_assert(RANDOMX_ARGON_MEMORY % (RANDOMX_ARGON_LANES * ARGON2_SYNC_POINTS) == 0, "RANDOMX_ARGON_MEMORY - invalid value");
|
|
||||||
static_assert(RANDOMX_ARGON_GROWTH % (RANDOMX_ARGON_LANES * ARGON2_SYNC_POINTS) == 0, "RANDOMX_ARGON_GROWTH - invalid value");
|
|
||||||
|
|
||||||
void argonFill(Cache& cache, const void* seed, size_t seedSize) {
|
|
||||||
uint32_t memory_blocks, segment_length;
|
|
||||||
argon2_instance_t instance;
|
|
||||||
argon2_context context;
|
|
||||||
|
|
||||||
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)ArgonSaltSize;
|
|
||||||
context.secret = NULL;
|
|
||||||
context.secretlen = 0;
|
|
||||||
context.ad = NULL;
|
|
||||||
context.adlen = 0;
|
|
||||||
context.t_cost = RANDOMX_ARGON_ITERATIONS;
|
|
||||||
context.m_cost = cache.size / ArgonBlockSize;
|
|
||||||
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 */
|
|
||||||
/* Minimum memory_blocks = 8L blocks, where L is the number of lanes */
|
|
||||||
memory_blocks = context.m_cost;
|
|
||||||
|
|
||||||
segment_length = memory_blocks / (context.lanes * ARGON2_SYNC_POINTS);
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (instance.threads > instance.lanes) {
|
|
||||||
instance.threads = instance.lanes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 3. Initialization: Hashing inputs, allocating memory, filling first
|
|
||||||
* blocks
|
|
||||||
*/
|
|
||||||
argon_initialize(&instance, &context);
|
|
||||||
|
|
||||||
fill_memory_blocks(&instance);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2018 tevador
|
|
||||||
|
|
||||||
This file is part of RandomX.
|
|
||||||
|
|
||||||
RandomX 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.
|
|
||||||
|
|
||||||
RandomX 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 RandomX. If not, see<http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <new>
|
|
||||||
#include "common.hpp"
|
|
||||||
#include "intrinPortable.h"
|
|
||||||
#include "virtualMemory.hpp"
|
|
||||||
|
|
||||||
namespace RandomX {
|
|
||||||
|
|
||||||
void argonFill(Cache& cache, const void* seed, size_t seedSize);
|
|
||||||
|
|
||||||
inline uint8_t* allocCache(size_t size, bool largePages) {
|
|
||||||
if (largePages) {
|
|
||||||
return (uint8_t*)allocLargePagesMemory(size);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
void* ptr = _mm_malloc(size, CacheLineSize);
|
|
||||||
if (ptr == nullptr)
|
|
||||||
throw std::bad_alloc();
|
|
||||||
return (uint8_t*)ptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void deallocCache(Cache cache, bool largePages) {
|
|
||||||
if (largePages) {
|
|
||||||
freePagedMemory(cache.memory, cache.size);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_mm_free(cache.memory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2018 tevador
|
||||||
|
|
||||||
|
This file is part of RandomX.
|
||||||
|
|
||||||
|
RandomX 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.
|
||||||
|
|
||||||
|
RandomX 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 RandomX. If not, see<http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "InterpretedLightVirtualMachine.hpp"
|
||||||
|
#include "dataset.hpp"
|
||||||
|
|
||||||
|
namespace randomx {
|
||||||
|
|
||||||
|
template<class Allocator, bool softAes>
|
||||||
|
void InterpretedLightVm<Allocator, softAes>::setCache(randomx_cache* cache) {
|
||||||
|
mem.memory = cache->memory;
|
||||||
|
//datasetRange = (size - RANDOMX_DATASET_SIZE + CacheLineSize) / CacheLineSize;
|
||||||
|
cachePtr = cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Allocator, bool softAes>
|
||||||
|
void InterpretedLightVm<Allocator, softAes>::datasetRead(uint32_t address, int_reg_t(&r)[8]) {
|
||||||
|
uint32_t blockNumber = address / CacheLineSize;
|
||||||
|
int_reg_t rl[8];
|
||||||
|
|
||||||
|
initDatasetBlock(cachePtr, (uint8_t*)rl, blockNumber);
|
||||||
|
|
||||||
|
for (unsigned q = 0; q < 8; ++q)
|
||||||
|
r[q] ^= rl[q];
|
||||||
|
}
|
||||||
|
|
||||||
|
template class InterpretedLightVm<AlignedAllocator<CacheLineSize>, false>;
|
||||||
|
template class InterpretedLightVm<AlignedAllocator<CacheLineSize>, true>;
|
||||||
|
template class InterpretedLightVm<LargePageAllocator, false>;
|
||||||
|
template class InterpretedLightVm<LargePageAllocator, true>;
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2018 tevador
|
||||||
|
|
||||||
|
This file is part of RandomX.
|
||||||
|
|
||||||
|
RandomX 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.
|
||||||
|
|
||||||
|
RandomX 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 RandomX. If not, see<http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
#include "InterpretedVirtualMachine.hpp"
|
||||||
|
#include "superscalar_program.hpp"
|
||||||
|
|
||||||
|
namespace randomx {
|
||||||
|
|
||||||
|
template<class Allocator, bool softAes>
|
||||||
|
class InterpretedLightVm : public InterpretedVm<Allocator, softAes> {
|
||||||
|
public:
|
||||||
|
using VmBase<Allocator, softAes>::mem;
|
||||||
|
void* operator new(size_t size) {
|
||||||
|
void* ptr = AlignedAllocator<CacheLineSize>::allocMemory(size);
|
||||||
|
if (ptr == nullptr)
|
||||||
|
throw std::bad_alloc();
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
void operator delete(void* ptr) {
|
||||||
|
AlignedAllocator<CacheLineSize>::freeMemory(ptr, sizeof(InterpretedLightVm));
|
||||||
|
}
|
||||||
|
void setDataset(randomx_dataset* dataset) override { }
|
||||||
|
void setCache(randomx_cache* cache) override;
|
||||||
|
protected:
|
||||||
|
virtual void datasetRead(uint32_t address, int_reg_t(&r)[8]);
|
||||||
|
private:
|
||||||
|
randomx_cache* cachePtr;
|
||||||
|
};
|
||||||
|
|
||||||
|
using InterpretedLightVmDefault = InterpretedLightVm<AlignedAllocator<CacheLineSize>, true>;
|
||||||
|
using InterpretedLightVmHardAes = InterpretedLightVm<AlignedAllocator<CacheLineSize>, false>;
|
||||||
|
using InterpretedLightVmLargePage = InterpretedLightVm<LargePageAllocator, false>;
|
||||||
|
using InterpretedLightVmLargePageHardAes = InterpretedLightVm<LargePageAllocator, true>;
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2019 tevador
|
||||||
|
|
||||||
|
This file is part of RandomX.
|
||||||
|
|
||||||
|
RandomX 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.
|
||||||
|
|
||||||
|
RandomX 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 RandomX. If not, see<http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "allocator.hpp"
|
||||||
|
#include "virtualMemory.hpp"
|
||||||
|
#include "intrinPortable.h"
|
||||||
|
#include "common.hpp"
|
||||||
|
|
||||||
|
namespace randomx {
|
||||||
|
|
||||||
|
template<size_t alignment>
|
||||||
|
void* AlignedAllocator<alignment>::allocMemory(size_t count) {
|
||||||
|
return _mm_malloc(count, alignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t alignment>
|
||||||
|
void AlignedAllocator<alignment>::freeMemory(void* ptr, size_t count) {
|
||||||
|
_mm_free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template void* AlignedAllocator<CacheLineSize>::allocMemory(size_t count);
|
||||||
|
template void AlignedAllocator<CacheLineSize>::freeMemory(void* ptr, size_t count);
|
||||||
|
template void* AlignedAllocator<sizeof(__m128i)>::allocMemory(size_t count);
|
||||||
|
template void AlignedAllocator<sizeof(__m128i)>::freeMemory(void* ptr, size_t count);
|
||||||
|
|
||||||
|
void* LargePageAllocator::allocMemory(size_t count) {
|
||||||
|
return allocLargePagesMemory(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LargePageAllocator::freeMemory(void* ptr, size_t count) {
|
||||||
|
freePagedMemory(ptr, count);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2019 tevador
|
||||||
|
|
||||||
|
This file is part of RandomX.
|
||||||
|
|
||||||
|
RandomX 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.
|
||||||
|
|
||||||
|
RandomX 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 RandomX. If not, see<http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace randomx {
|
||||||
|
|
||||||
|
template<size_t alignment>
|
||||||
|
struct AlignedAllocator {
|
||||||
|
static void* allocMemory(size_t);
|
||||||
|
static void freeMemory(void*, size_t);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LargePageAllocator {
|
||||||
|
static void* allocMemory(size_t);
|
||||||
|
static void freeMemory(void*, size_t);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,209 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2019 tevador
|
||||||
|
|
||||||
|
This file is part of RandomX.
|
||||||
|
|
||||||
|
RandomX 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.
|
||||||
|
|
||||||
|
RandomX 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 RandomX. If not, see<http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "randomx.h"
|
||||||
|
#include "dataset.hpp"
|
||||||
|
#include "VirtualMachine.hpp"
|
||||||
|
#include "./InterpretedVirtualMachine.hpp"
|
||||||
|
#include "./InterpretedLightVirtualMachine.hpp"
|
||||||
|
#include "./CompiledVirtualMachine.hpp"
|
||||||
|
#include "./CompiledLightVirtualMachine.hpp"
|
||||||
|
#include "virtualMemory.hpp"
|
||||||
|
#include "blake2/blake2.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
randomx_cache *randomx_alloc_cache(randomx_flags flags) {
|
||||||
|
randomx_cache *cache;
|
||||||
|
switch (flags & (RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES))
|
||||||
|
{
|
||||||
|
case RANDOMX_FLAG_DEFAULT:
|
||||||
|
cache = new randomx::CacheDefault();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RANDOMX_FLAG_JIT:
|
||||||
|
cache = new randomx::CacheWithJitDefault();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RANDOMX_FLAG_LARGE_PAGES:
|
||||||
|
cache = new randomx::CacheLargePage();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES:
|
||||||
|
cache = new randomx::CacheWithJitLargePage();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
UNREACHABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cache->allocate()) {
|
||||||
|
delete cache;
|
||||||
|
cache = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
void randomx_init_cache(randomx_cache *cache, const void *seed, size_t seedSize) {
|
||||||
|
cache->initialize(seed, seedSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void randomx_release_cache(randomx_cache* cache) {
|
||||||
|
delete cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
randomx_dataset *randomx_alloc_dataset(randomx_flags flags) {
|
||||||
|
randomx_dataset *dataset;
|
||||||
|
if (flags & RANDOMX_FLAG_LARGE_PAGES) {
|
||||||
|
dataset = new randomx::DatasetLargePage();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dataset = new randomx::DatasetDefault();
|
||||||
|
}
|
||||||
|
if (!dataset->allocate()) {
|
||||||
|
delete dataset;
|
||||||
|
dataset = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dataset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void randomx_init_dataset(randomx_dataset *dataset, randomx_cache *cache, unsigned long startBlock, unsigned long blockCount) {
|
||||||
|
randomx::DatasetInitFunc dsfunc = cache->getInitFunc();
|
||||||
|
dsfunc(cache, dataset->memory + startBlock * randomx::CacheLineSize, startBlock, startBlock + blockCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void randomx_release_dataset(randomx_dataset *dataset) {
|
||||||
|
delete dataset;
|
||||||
|
}
|
||||||
|
|
||||||
|
randomx_vm *randomx_create_vm(randomx_flags flags) {
|
||||||
|
randomx_vm *vm;
|
||||||
|
switch (flags & (RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES)) {
|
||||||
|
case RANDOMX_FLAG_DEFAULT: //0
|
||||||
|
vm = new randomx::InterpretedLightVmDefault();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RANDOMX_FLAG_FULL_MEM: //1
|
||||||
|
vm = new randomx::InterpretedVmDefault();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RANDOMX_FLAG_JIT: //2
|
||||||
|
vm = new randomx::CompiledLightVmDefault();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT: //3
|
||||||
|
vm = new randomx::CompiledVmDefault();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RANDOMX_FLAG_HARD_AES: //4
|
||||||
|
vm = new randomx::InterpretedLightVmHardAes();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_HARD_AES: //5
|
||||||
|
vm = new randomx::InterpretedVmHardAes();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES: //6
|
||||||
|
vm = new randomx::CompiledLightVmHardAes();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES: //7
|
||||||
|
vm = new randomx::CompiledVmHardAes();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RANDOMX_FLAG_LARGE_PAGES: //8
|
||||||
|
vm = new randomx::InterpretedLightVmLargePage();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_LARGE_PAGES: //9
|
||||||
|
vm = new randomx::InterpretedVmLargePage();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES: //10
|
||||||
|
vm = new randomx::CompiledLightVmLargePage();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES: //11
|
||||||
|
vm = new randomx::CompiledVmLargePage();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES: //12
|
||||||
|
vm = new randomx::InterpretedLightVmLargePageHardAes();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES: //13
|
||||||
|
vm = new randomx::InterpretedVmLargePageHardAes();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES: //14
|
||||||
|
vm = new randomx::CompiledLightVmLargePageHardAes();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES: //15
|
||||||
|
vm = new randomx::CompiledVmLargePageHardAes();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
UNREACHABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vm->allocate()) {
|
||||||
|
delete vm;
|
||||||
|
vm = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vm;
|
||||||
|
}
|
||||||
|
|
||||||
|
void randomx_vm_set_cache(randomx_vm *machine, randomx_cache* cache) {
|
||||||
|
machine->setCache(cache);
|
||||||
|
}
|
||||||
|
|
||||||
|
void randomx_vm_set_dataset(randomx_vm *machine, randomx_dataset *dataset) {
|
||||||
|
machine->setDataset(dataset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void randomx_destroy_vm(randomx_vm *machine) {
|
||||||
|
delete machine;
|
||||||
|
}
|
||||||
|
|
||||||
|
void randomx_calculate_hash(randomx_vm *machine, void *input, size_t inputSize, void *output) {
|
||||||
|
alignas(16) uint64_t hash[8];
|
||||||
|
blake2b(hash, sizeof(hash), input, inputSize, nullptr, 0);
|
||||||
|
machine->generate(&hash, machine->scratchpad, randomx::ScratchpadSize);
|
||||||
|
//fillAes1Rx4<false>((void*)hash, RANDOMX_SCRATCHPAD_L3, machine->scratchpad);
|
||||||
|
//dump((char*)scratchpad, RANDOMX_SCRATCHPAD_L3, "spad-before.txt");
|
||||||
|
machine->resetRoundingMode();
|
||||||
|
for (int chain = 0; chain < RANDOMX_PROGRAM_COUNT - 1; ++chain) {
|
||||||
|
machine->generate(&hash, &machine->program, sizeof(randomx::Program));
|
||||||
|
//fillAes1Rx4<softAes>((void*)hash, sizeof(RandomX::Program), vm->getProgramBuffer());
|
||||||
|
machine->initialize();
|
||||||
|
machine->execute();
|
||||||
|
blake2b(hash, sizeof(hash), &machine->reg, sizeof(machine->reg), nullptr, 0);
|
||||||
|
}
|
||||||
|
machine->generate((void*)hash, &machine->program, sizeof(randomx::Program));
|
||||||
|
//fillAes1Rx4<softAes>((void*)hash, sizeof(RandomX::Program), vm->getProgramBuffer());
|
||||||
|
machine->initialize();
|
||||||
|
machine->execute();
|
||||||
|
machine->getFinalResult(output, 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2019 tevador
|
||||||
|
|
||||||
|
This file is part of RandomX.
|
||||||
|
|
||||||
|
RandomX 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.
|
||||||
|
|
||||||
|
RandomX 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 RandomX. If not, see<http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RANDOMX_H
|
||||||
|
#define RANDOMX_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Minimal usage example:
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
#include "randomx.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
const char mySeed[] = "RandomX example seed";
|
||||||
|
const char myInput[] = "RandomX example input";
|
||||||
|
char hash[RANDOMX_HASH_SIZE];
|
||||||
|
|
||||||
|
randomx_cache *myCache = randomx_alloc_cache(RANDOMX_FLAG_DEFAULT);
|
||||||
|
randomx_init_cache(myCache, mySeed, sizeof mySeed);
|
||||||
|
randomx_vm *myMachine = randomx_create_vm(RANDOMX_FLAG_DEFAULT);
|
||||||
|
randomx_vm_set_cache(myMachine, myCache);
|
||||||
|
|
||||||
|
randomx_calculate_hash(myMachine, myInput, sizeof myInput, hash);
|
||||||
|
|
||||||
|
randomx_destroy_vm(myMachine);
|
||||||
|
randomx_release_cache(myCache);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < RANDOMX_HASH_SIZE; ++i)
|
||||||
|
printf("%02x", hash[i]);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Optimized usage example:
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
#include "randomx.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
const char mySeed[] = "RandomX example seed";
|
||||||
|
const char myInput[] = "RandomX example input";
|
||||||
|
char hash[RANDOMX_HASH_SIZE];
|
||||||
|
|
||||||
|
randomx_cache *myCache = randomx_alloc_cache(RANDOMX_FLAG_JIT | RANDOMX_FLAG_LARGE_PAGES);
|
||||||
|
randomx_init_cache(myCache, mySeed, sizeof mySeed);
|
||||||
|
|
||||||
|
randomx_dataset *myDataset = randomx_alloc_dataset(RANDOMX_FLAG_LARGE_PAGES);
|
||||||
|
randomx_init_dataset(myDataset, myCache, 0, RANDOMX_DATASET_BLOCKS);
|
||||||
|
randomx_release_cache(myCache);
|
||||||
|
|
||||||
|
randomx_vm *myMachine = randomx_create_vm(RANDOMX_FLAG_FULL_MEM | RANDOMX_FLAG_JIT | RANDOMX_FLAG_HARD_AES | RANDOMX_FLAG_LARGE_PAGES);
|
||||||
|
randomx_vm_set_dataset(myMachine, myDataset);
|
||||||
|
|
||||||
|
randomx_calculate_hash(myMachine, myInput, sizeof myInput, hash);
|
||||||
|
|
||||||
|
randomx_destroy_vm(myMachine);
|
||||||
|
randomx_release_dataset(myDataset);
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < RANDOMX_HASH_SIZE; ++i)
|
||||||
|
printf("%02x", hash[i]);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#define RANDOMX_HASH_SIZE 32
|
||||||
|
#define RANDOMX_DATASET_BLOCKS 33554432UL
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
RANDOMX_FLAG_DEFAULT = 0,
|
||||||
|
RANDOMX_FLAG_FULL_MEM = 1,
|
||||||
|
RANDOMX_FLAG_JIT = 2,
|
||||||
|
RANDOMX_FLAG_HARD_AES = 4,
|
||||||
|
RANDOMX_FLAG_LARGE_PAGES = 8,
|
||||||
|
} randomx_flags;
|
||||||
|
|
||||||
|
typedef struct randomx_dataset randomx_dataset;
|
||||||
|
typedef struct randomx_cache randomx_cache;
|
||||||
|
typedef struct randomx_vm randomx_vm;
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
randomx_cache *randomx_alloc_cache(randomx_flags flags);
|
||||||
|
void randomx_init_cache(randomx_cache *cache, const void *seed, size_t seedSize);
|
||||||
|
void randomx_release_cache(randomx_cache* cache);
|
||||||
|
|
||||||
|
randomx_dataset *randomx_alloc_dataset(randomx_flags flags);
|
||||||
|
void randomx_init_dataset(randomx_dataset *dataset, randomx_cache *cache, unsigned long startBlock, unsigned long blockCount);
|
||||||
|
void randomx_release_dataset(randomx_dataset *dataset);
|
||||||
|
|
||||||
|
randomx_vm *randomx_create_vm(randomx_flags flags);
|
||||||
|
void randomx_vm_set_cache(randomx_vm *machine, randomx_cache* cache);
|
||||||
|
void randomx_vm_set_dataset(randomx_vm *machine, randomx_dataset *dataset);
|
||||||
|
void randomx_destroy_vm(randomx_vm *machine);
|
||||||
|
|
||||||
|
void randomx_calculate_hash(randomx_vm *machine, void *input, size_t inputSize, void *output);
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2019 tevador
|
||||||
|
|
||||||
|
This file is part of RandomX.
|
||||||
|
|
||||||
|
RandomX 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.
|
||||||
|
|
||||||
|
RandomX 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 RandomX. If not, see<http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include "Instruction.hpp"
|
||||||
|
#include "configuration.h"
|
||||||
|
|
||||||
|
namespace randomx {
|
||||||
|
|
||||||
|
class SuperscalarProgram {
|
||||||
|
public:
|
||||||
|
Instruction& operator()(int pc) {
|
||||||
|
return programBuffer[pc];
|
||||||
|
}
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const SuperscalarProgram& p) {
|
||||||
|
p.print(os);
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
uint32_t getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
void setSize(uint32_t val) {
|
||||||
|
size = val;
|
||||||
|
}
|
||||||
|
int getAddressRegister() {
|
||||||
|
return addrReg;
|
||||||
|
}
|
||||||
|
void setAddressRegister(uint32_t val) {
|
||||||
|
addrReg = val;
|
||||||
|
}
|
||||||
|
double ipc;
|
||||||
|
int codeSize;
|
||||||
|
int macroOps;
|
||||||
|
int decodeCycles;
|
||||||
|
int cpuLatency;
|
||||||
|
int asicLatency;
|
||||||
|
int mulCount;
|
||||||
|
int cpuLatencies[8];
|
||||||
|
int asicLatencies[8];
|
||||||
|
private:
|
||||||
|
void print(std::ostream& os) const {
|
||||||
|
for (unsigned i = 0; i < size; ++i) {
|
||||||
|
auto instr = programBuffer[i];
|
||||||
|
os << instr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Instruction programBuffer[RANDOMX_SUPERSCALAR_MAX_SIZE];
|
||||||
|
uint32_t size;
|
||||||
|
int addrReg;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in new issue