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…
	
	Add table
		Add a link
		
	
		Reference in a new issue