Reduced the number of virtual calls per hash

This commit is contained in:
tevador 2019-04-20 12:49:24 +02:00
parent 296e77eebc
commit d7276d5786
9 changed files with 62 additions and 43 deletions

View file

@ -25,17 +25,18 @@ namespace randomx {
template<class Allocator, bool softAes>
void CompiledLightVm<Allocator, softAes>::setCache(randomx_cache* cache) {
this->mem.memory = cache->memory;
//datasetRange = (size - RANDOMX_DATASET_SIZE + CacheLineSize) / CacheLineSize;
this->compiler.generateSuperscalarHash(cache->programs, cache->reciprocalCache);
mem.memory = cache->memory;
compiler.generateSuperscalarHash(cache->programs, cache->reciprocalCache);
//datasetBasePtr = ds.dataset.memory;
}
template<class Allocator, bool softAes>
void CompiledLightVm<Allocator, softAes>::initialize() {
void CompiledLightVm<Allocator, softAes>::run(void* seed) {
VmBase<Allocator, softAes>::generateProgram(seed);
randomx_vm::initialize();
this->compiler.generateProgramLight(this->program, this->config);
//mem.ds.dataset.memory = datasetBasePtr + (datasetBase * CacheLineSize);
compiler.generateProgramLight(program, config);
//mem.memory = datasetBasePtr + (datasetBase * CacheLineSize);
CompiledVm<Allocator, softAes>::execute();
}
template class CompiledLightVm<AlignedAllocator<CacheLineSize>, false>;

View file

@ -40,7 +40,12 @@ namespace randomx {
}
void setCache(randomx_cache* cache) override;
void setDataset(randomx_dataset* dataset) override {}
void initialize() override;
void run(void* seed) override;
using CompiledVm<Allocator, softAes>::mem;
using CompiledVm<Allocator, softAes>::compiler;
using CompiledVm<Allocator, softAes>::program;
using CompiledVm<Allocator, softAes>::config;
};
using CompiledLightVmDefault = CompiledLightVm<AlignedAllocator<CacheLineSize>, true>;

View file

@ -19,32 +19,31 @@ along with RandomX. If not, see<http://www.gnu.org/licenses/>.
#include "CompiledVirtualMachine.hpp"
#include "common.hpp"
#include <stdexcept>
namespace randomx {
static_assert(sizeof(MemoryRegisters) == 2 * sizeof(addr_t) + sizeof(uintptr_t), "Invalid alignment of struct randomx::MemoryRegisters");
static_assert(sizeof(RegisterFile) == 256, "Invalid alignment of struct randomx::RegisterFile");
template<class Allocator, bool softAes>
void CompiledVm<Allocator, softAes>::setDataset(randomx_dataset* dataset) {
this->mem.memory = dataset->memory;
//datasetRange = (size - RANDOMX_DATASET_SIZE + CacheLineSize) / CacheLineSize;
//datasetBasePtr = ds.dataset.memory;
mem.memory = dataset->memory;
//datasetBasePtr = dataset.memory;
}
template<class Allocator, bool softAes>
void CompiledVm<Allocator, softAes>::initialize() {
void CompiledVm<Allocator, softAes>::run(void* seed) {
VmBase<Allocator, softAes>::generateProgram(seed);
randomx_vm::initialize();
this->compiler.generateProgram(this->program, this->config);
//mem.ds.dataset.memory = datasetBasePtr + (datasetBase * CacheLineSize);
compiler.generateProgram(program, config);
//mem.memory = datasetBasePtr + (datasetBase * CacheLineSize);
execute();
}
template<class Allocator, bool softAes>
void CompiledVm<Allocator, softAes>::execute() {
//executeProgram(reg, mem, scratchpad, InstructionCount);
compiler.getProgramFunc()(this->reg, this->mem, this->scratchpad, RANDOMX_PROGRAM_ITERATIONS);
compiler.getProgramFunc()(reg, mem, scratchpad, RANDOMX_PROGRAM_ITERATIONS);
}
template class CompiledVm<AlignedAllocator<CacheLineSize>, false>;

View file

@ -42,9 +42,16 @@ namespace randomx {
AlignedAllocator<CacheLineSize>::freeMemory(ptr, sizeof(CompiledVm));
}
void setDataset(randomx_dataset* dataset) override;
void execute() override;
void initialize() override;
void run(void* seed) override;
using VmBase<Allocator, softAes>::mem;
using VmBase<Allocator, softAes>::program;
using VmBase<Allocator, softAes>::config;
using VmBase<Allocator, softAes>::reg;
using VmBase<Allocator, softAes>::scratchpad;
protected:
void execute();
JitCompilerX86 compiler;
uint8_t* datasetBasePtr;
};

View file

@ -48,12 +48,14 @@ namespace randomx {
}
template<class Allocator, bool softAes>
void InterpretedVm<Allocator, softAes>::initialize() {
void InterpretedVm<Allocator, softAes>::run(void* seed) {
VmBase<Allocator, softAes>::generateProgram(seed);
randomx_vm::initialize();
for (unsigned i = 0; i < RANDOMX_PROGRAM_SIZE; ++i) {
program(i).src %= RegistersCount;
program(i).dst %= RegistersCount;
}
execute();
}
template<class Allocator, bool softAes>

View file

@ -67,12 +67,12 @@ namespace randomx {
void operator delete(void* ptr) {
AlignedAllocator<CacheLineSize>::freeMemory(ptr, sizeof(InterpretedVm));
}
void execute() override;
void run(void* seed) override;
void setDataset(randomx_dataset* dataset) override;
void initialize() override;
protected:
virtual void datasetRead(uint32_t blockNumber, int_reg_t(&r)[8]);
private:
void execute();
void precompileProgram(int_reg_t(&r)[8], __m128d (&f)[4], __m128d (&e)[4], __m128d (&a)[4]);
void executeBytecode(int_reg_t(&r)[8], __m128d (&f)[4], __m128d (&e)[4], __m128d (&a)[4]);
void executeBytecode(int& i, int_reg_t(&r)[8], __m128d (&f)[4], __m128d (&e)[4], __m128d (&a)[4]);

View file

@ -104,17 +104,22 @@ namespace randomx {
return scratchpad != nullptr;
}
template<class Allocator, bool softAes>
void VmBase<Allocator, softAes>::generate(void* seed, void* buffer, size_t bufferSize) {
fillAes1Rx4<softAes>(seed, bufferSize, buffer);
}
template<class Allocator, bool softAes>
void VmBase<Allocator, softAes>::getFinalResult(void* out, size_t outSize) {
hashAes1Rx4<softAes>(scratchpad, ScratchpadSize, &reg.a);
blake2b(out, outSize, &reg, sizeof(RegisterFile), nullptr, 0);
}
template<class Allocator, bool softAes>
void VmBase<Allocator, softAes>::initScratchpad(void* seed) {
fillAes1Rx4<softAes>(seed, ScratchpadSize, scratchpad);
}
template<class Allocator, bool softAes>
void VmBase<Allocator, softAes>::generateProgram(void* seed) {
fillAes1Rx4<softAes>(seed, sizeof(program), &program);
}
template class VmBase<AlignedAllocator<CacheLineSize>, false>;
template class VmBase<AlignedAllocator<CacheLineSize>, true>;
template class VmBase<LargePageAllocator, false>;

View file

@ -25,17 +25,22 @@ along with RandomX. If not, see<http://www.gnu.org/licenses/>.
#include "Program.hpp"
/* Global namespace for C binding */
struct randomx_vm {
class randomx_vm {
public:
virtual ~randomx_vm() = 0;
virtual bool allocate() = 0;
virtual void generate(void* seed, void* buffer, size_t bufferSize) = 0;
void resetRoundingMode();
virtual void initialize();
virtual void execute() = 0;
virtual void getFinalResult(void* out, size_t outSize) = 0;
virtual void setDataset(randomx_dataset* dataset) { }
virtual void setCache(randomx_cache* cache) { }
virtual void initScratchpad(void* seed) = 0;
virtual void run(void* seed) = 0;
void resetRoundingMode();
randomx::RegisterFile *getRegisterFile() {
return &reg;
}
protected:
void initialize();
alignas(64) randomx::Program program;
alignas(64) randomx::RegisterFile reg;
alignas(16) randomx::ProgramConfiguration config;
@ -50,8 +55,10 @@ namespace randomx {
public:
~VmBase() override;
bool allocate() override;
void generate(void* seed, void* buffer, size_t bufferSize) override;
void initScratchpad(void* seed) override;
void getFinalResult(void* out, size_t outSize) override;
protected:
void generateProgram(void* seed);
};
}

View file

@ -188,21 +188,14 @@ extern "C" {
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);
machine->initScratchpad(&hash);
//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->run(&hash);
blake2b(hash, sizeof(hash), machine->getRegisterFile(), sizeof(randomx::RegisterFile), 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->run(&hash);
machine->getFinalResult(output, 64);
}