Просмотр исходного кода

Reduced the number of virtual calls per hash

tevador 7 лет назад
Родитель
Сommit
d7276d5786

+ 7 - 6
src/CompiledLightVirtualMachine.cpp

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

+ 6 - 1
src/CompiledLightVirtualMachine.hpp

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

+ 8 - 9
src/CompiledVirtualMachine.cpp

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

+ 9 - 2
src/CompiledVirtualMachine.hpp

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

+ 3 - 1
src/InterpretedVirtualMachine.cpp

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

+ 2 - 2
src/InterpretedVirtualMachine.hpp

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

+ 10 - 5
src/VirtualMachine.cpp

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

+ 13 - 6
src/VirtualMachine.hpp

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

+ 4 - 11
src/randomx.cpp

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