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> template<class Allocator, bool softAes>
void CompiledLightVm<Allocator, softAes>::setCache(randomx_cache* cache) { void CompiledLightVm<Allocator, softAes>::setCache(randomx_cache* cache) {
this->mem.memory = cache->memory; mem.memory = cache->memory;
//datasetRange = (size - RANDOMX_DATASET_SIZE + CacheLineSize) / CacheLineSize; compiler.generateSuperscalarHash(cache->programs, cache->reciprocalCache);
this->compiler.generateSuperscalarHash(cache->programs, cache->reciprocalCache);
//datasetBasePtr = ds.dataset.memory; //datasetBasePtr = ds.dataset.memory;
} }
template<class Allocator, bool softAes> 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(); randomx_vm::initialize();
this->compiler.generateProgramLight(this->program, this->config); compiler.generateProgramLight(program, config);
//mem.ds.dataset.memory = datasetBasePtr + (datasetBase * CacheLineSize); //mem.memory = datasetBasePtr + (datasetBase * CacheLineSize);
CompiledVm<Allocator, softAes>::execute();
} }
template class CompiledLightVm<AlignedAllocator<CacheLineSize>, false>; template class CompiledLightVm<AlignedAllocator<CacheLineSize>, false>;

View file

@ -40,7 +40,12 @@ namespace randomx {
} }
void setCache(randomx_cache* cache) override; void setCache(randomx_cache* cache) override;
void setDataset(randomx_dataset* dataset) 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>; 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 "CompiledVirtualMachine.hpp"
#include "common.hpp" #include "common.hpp"
#include <stdexcept>
namespace randomx { namespace randomx {
static_assert(sizeof(MemoryRegisters) == 2 * sizeof(addr_t) + sizeof(uintptr_t), "Invalid alignment of struct randomx::MemoryRegisters"); 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"); static_assert(sizeof(RegisterFile) == 256, "Invalid alignment of struct randomx::RegisterFile");
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) {
this->mem.memory = dataset->memory; mem.memory = dataset->memory;
//datasetRange = (size - RANDOMX_DATASET_SIZE + CacheLineSize) / CacheLineSize; //datasetBasePtr = dataset.memory;
//datasetBasePtr = ds.dataset.memory;
} }
template<class Allocator, bool softAes> 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(); randomx_vm::initialize();
this->compiler.generateProgram(this->program, this->config); compiler.generateProgram(program, config);
//mem.ds.dataset.memory = datasetBasePtr + (datasetBase * CacheLineSize); //mem.memory = datasetBasePtr + (datasetBase * CacheLineSize);
execute();
} }
template<class Allocator, bool softAes> template<class Allocator, bool softAes>
void CompiledVm<Allocator, softAes>::execute() { void CompiledVm<Allocator, softAes>::execute() {
//executeProgram(reg, mem, scratchpad, InstructionCount); //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>; template class CompiledVm<AlignedAllocator<CacheLineSize>, false>;

View file

@ -42,9 +42,16 @@ namespace randomx {
AlignedAllocator<CacheLineSize>::freeMemory(ptr, sizeof(CompiledVm)); AlignedAllocator<CacheLineSize>::freeMemory(ptr, sizeof(CompiledVm));
} }
void setDataset(randomx_dataset* dataset) override; void setDataset(randomx_dataset* dataset) override;
void execute() override; void run(void* seed) override;
void initialize() 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: protected:
void execute();
JitCompilerX86 compiler; JitCompilerX86 compiler;
uint8_t* datasetBasePtr; uint8_t* datasetBasePtr;
}; };

View file

@ -48,12 +48,14 @@ namespace randomx {
} }
template<class Allocator, bool softAes> 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(); randomx_vm::initialize();
for (unsigned i = 0; i < RANDOMX_PROGRAM_SIZE; ++i) { for (unsigned i = 0; i < RANDOMX_PROGRAM_SIZE; ++i) {
program(i).src %= RegistersCount; program(i).src %= RegistersCount;
program(i).dst %= RegistersCount; program(i).dst %= RegistersCount;
} }
execute();
} }
template<class Allocator, bool softAes> template<class Allocator, bool softAes>

View file

@ -67,12 +67,12 @@ namespace randomx {
void operator delete(void* ptr) { void operator delete(void* ptr) {
AlignedAllocator<CacheLineSize>::freeMemory(ptr, sizeof(InterpretedVm)); AlignedAllocator<CacheLineSize>::freeMemory(ptr, sizeof(InterpretedVm));
} }
void execute() override; void run(void* seed) override;
void setDataset(randomx_dataset* dataset) override; void setDataset(randomx_dataset* dataset) override;
void initialize() override;
protected: protected:
virtual void datasetRead(uint32_t blockNumber, int_reg_t(&r)[8]); virtual void datasetRead(uint32_t blockNumber, int_reg_t(&r)[8]);
private: private:
void execute();
void precompileProgram(int_reg_t(&r)[8], __m128d (&f)[4], __m128d (&e)[4], __m128d (&a)[4]); 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_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]); 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; 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> template<class Allocator, bool softAes>
void VmBase<Allocator, softAes>::getFinalResult(void* out, size_t outSize) { void VmBase<Allocator, softAes>::getFinalResult(void* out, size_t outSize) {
hashAes1Rx4<softAes>(scratchpad, ScratchpadSize, &reg.a); hashAes1Rx4<softAes>(scratchpad, ScratchpadSize, &reg.a);
blake2b(out, outSize, &reg, sizeof(RegisterFile), nullptr, 0); 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>, false>;
template class VmBase<AlignedAllocator<CacheLineSize>, true>; template class VmBase<AlignedAllocator<CacheLineSize>, true>;
template class VmBase<LargePageAllocator, false>; 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" #include "Program.hpp"
/* Global namespace for C binding */ /* Global namespace for C binding */
struct randomx_vm { class randomx_vm {
public:
virtual ~randomx_vm() = 0; virtual ~randomx_vm() = 0;
virtual bool allocate() = 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 getFinalResult(void* out, size_t outSize) = 0;
virtual void setDataset(randomx_dataset* dataset) { } virtual void setDataset(randomx_dataset* dataset) { }
virtual void setCache(randomx_cache* cache) { } 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::Program program;
alignas(64) randomx::RegisterFile reg; alignas(64) randomx::RegisterFile reg;
alignas(16) randomx::ProgramConfiguration config; alignas(16) randomx::ProgramConfiguration config;
@ -50,8 +55,10 @@ namespace randomx {
public: public:
~VmBase() override; ~VmBase() override;
bool allocate() 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; 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) { void randomx_calculate_hash(randomx_vm *machine, void *input, size_t inputSize, void *output) {
alignas(16) uint64_t hash[8]; alignas(16) uint64_t hash[8];
blake2b(hash, sizeof(hash), input, inputSize, nullptr, 0); blake2b(hash, sizeof(hash), input, inputSize, nullptr, 0);
machine->generate(&hash, machine->scratchpad, randomx::ScratchpadSize); machine->initScratchpad(&hash);
//fillAes1Rx4<false>((void*)hash, RANDOMX_SCRATCHPAD_L3, machine->scratchpad);
//dump((char*)scratchpad, RANDOMX_SCRATCHPAD_L3, "spad-before.txt"); //dump((char*)scratchpad, RANDOMX_SCRATCHPAD_L3, "spad-before.txt");
machine->resetRoundingMode(); machine->resetRoundingMode();
for (int chain = 0; chain < RANDOMX_PROGRAM_COUNT - 1; ++chain) { for (int chain = 0; chain < RANDOMX_PROGRAM_COUNT - 1; ++chain) {
machine->generate(&hash, &machine->program, sizeof(randomx::Program)); machine->run(&hash);
//fillAes1Rx4<softAes>((void*)hash, sizeof(RandomX::Program), vm->getProgramBuffer()); blake2b(hash, sizeof(hash), machine->getRegisterFile(), sizeof(randomx::RegisterFile), nullptr, 0);
machine->initialize();
machine->execute();
blake2b(hash, sizeof(hash), &machine->reg, sizeof(machine->reg), nullptr, 0);
} }
machine->generate((void*)hash, &machine->program, sizeof(randomx::Program)); machine->run(&hash);
//fillAes1Rx4<softAes>((void*)hash, sizeof(RandomX::Program), vm->getProgramBuffer());
machine->initialize();
machine->execute();
machine->getFinalResult(output, 64); machine->getFinalResult(output, 64);
} }