mirror of
				https://git.wownero.com/wownero/RandomWOW.git
				synced 2024-08-15 00:23:14 +00:00 
			
		
		
		
	API documentation
'dataset block' -> 'dataset item' customizable benchmark seed
This commit is contained in:
		
							parent
							
								
									bc78b628ea
								
							
						
					
					
						commit
						87b8253374
					
				
					 8 changed files with 136 additions and 27 deletions
				
			
		|  | @ -59,7 +59,7 @@ namespace randomx { | |||
| 	constexpr uint32_t CacheLineAlignMask = (RANDOMX_DATASET_SIZE - 1) & ~(CacheLineSize - 1); | ||||
| 	constexpr uint32_t CacheSize = RANDOMX_ARGON_MEMORY * 1024; | ||||
| 
 | ||||
| 	static_assert(RANDOMX_DATASET_BLOCKS == RANDOMX_DATASET_SIZE / CacheLineSize, "Invalid value of RANDOMX_DATASET_BLOCKS"); | ||||
| 	static_assert(RANDOMX_DATASET_ITEMS == RANDOMX_DATASET_SIZE / CacheLineSize, "Invalid value of RANDOMX_DATASET_ITEMS"); | ||||
| 
 | ||||
| #ifdef TRACE | ||||
| 	constexpr bool trace = true; | ||||
|  |  | |||
|  | @ -180,11 +180,11 @@ namespace randomx { | |||
| 		return memory + (registerValue & mask) * CacheLineSize; | ||||
| 	} | ||||
| 
 | ||||
| 	void initDatasetBlock(randomx_cache* cache, uint8_t* out, uint64_t blockNumber) { | ||||
| 	void initDatasetItem(randomx_cache* cache, uint8_t* out, uint64_t itemNumber) { | ||||
| 		int_reg_t rl[8]; | ||||
| 		uint8_t* mixBlock; | ||||
| 		uint64_t registerValue = blockNumber; | ||||
| 		rl[0] = (blockNumber + 1) * superscalarMul0; | ||||
| 		uint64_t registerValue = itemNumber; | ||||
| 		rl[0] = (itemNumber + 1) * superscalarMul0; | ||||
| 		rl[1] = rl[0] ^ superscalarAdd1; | ||||
| 		rl[2] = rl[0] ^ superscalarAdd2; | ||||
| 		rl[3] = rl[0] ^ superscalarAdd3; | ||||
|  | @ -207,8 +207,8 @@ namespace randomx { | |||
| 		memcpy(out, &rl, CacheLineSize); | ||||
| 	} | ||||
| 
 | ||||
| 	void initDataset(randomx_cache* cache, uint8_t* dataset, uint32_t startBlock, uint32_t endBlock) { | ||||
| 		for (uint32_t blockNumber = startBlock; blockNumber < endBlock; ++blockNumber, dataset += CacheLineSize) | ||||
| 			initDatasetBlock(cache, dataset, blockNumber); | ||||
| 	void initDataset(randomx_cache* cache, uint8_t* dataset, uint32_t startItem, uint32_t endItem) { | ||||
| 		for (uint32_t itemNumber = startItem; itemNumber < endItem; ++itemNumber, dataset += CacheLineSize) | ||||
| 			initDatasetItem(cache, dataset, itemNumber); | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -73,6 +73,6 @@ namespace randomx { | |||
| 	using CacheLargePage = Cache<LargePageAllocator>; | ||||
| 	using CacheWithJitLargePage = CacheWithJit<LargePageAllocator>; | ||||
| 
 | ||||
| 	void initDatasetBlock(randomx_cache* cache, uint8_t* out, uint64_t blockNumber); | ||||
| 	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); | ||||
| } | ||||
|  |  | |||
|  | @ -90,9 +90,9 @@ extern "C" { | |||
| 		return dataset; | ||||
| 	} | ||||
| 
 | ||||
| 	void randomx_init_dataset(randomx_dataset *dataset, randomx_cache *cache, unsigned long startBlock, unsigned long blockCount) { | ||||
| 	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 + startBlock * randomx::CacheLineSize, startBlock, startBlock + blockCount); | ||||
| 		dsfunc(cache, dataset->memory + startItem * randomx::CacheLineSize, startItem, startItem + itemCount); | ||||
| 	} | ||||
| 
 | ||||
| 	void randomx_release_dataset(randomx_dataset *dataset) { | ||||
|  |  | |||
							
								
								
									
										112
									
								
								src/randomx.h
									
										
									
									
									
								
							
							
						
						
									
										112
									
								
								src/randomx.h
									
										
									
									
									
								
							|  | @ -23,7 +23,7 @@ along with RandomX.  If not, see<http://www.gnu.org/licenses/>. | |||
| #include <stddef.h> | ||||
| 
 | ||||
| #define RANDOMX_HASH_SIZE 32 | ||||
| #define RANDOMX_DATASET_BLOCKS 33554432UL | ||||
| #define RANDOMX_DATASET_ITEMS 33554432UL | ||||
| 
 | ||||
| typedef enum { | ||||
|   RANDOMX_FLAG_DEFAULT = 0, | ||||
|  | @ -41,19 +41,127 @@ typedef struct randomx_vm randomx_vm; | |||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| /**
 | ||||
|  * Creates a randomx_cache structure and allocates memory for RandomX Cache. | ||||
|  * | ||||
|  * @param flags is any combination of these 2 flags (each flag can be set or not set): | ||||
|  *        RANDOMX_FLAG_LARGE_PAGES - allocate memory in large pages | ||||
|  *        RANDOMX_FLAG_JIT - create cache structure with JIT compilation support; this makes | ||||
|  *                           subsequent Dataset initialization faster | ||||
|  * | ||||
|  * @return Pointer to an allocated randomx_cache structure. | ||||
|            NULL is returned if memory allocation fails or if the RANDOMX_FLAG_JIT | ||||
| 		   is set and JIT compilation is not supported on the current platform. | ||||
|  */ | ||||
| randomx_cache *randomx_alloc_cache(randomx_flags flags); | ||||
| 
 | ||||
| /**
 | ||||
|  * Initializes the cache memory and SuperscalarHash using the provided seed value. | ||||
|  * | ||||
|  * @param cache is a pointer to a previously allocated randomx_cache structure. Must not be NULL. | ||||
|  * @param seed is a pointer to memory which contains the seed value. Must not be NULL. | ||||
|  * @param seedSize is the number of bytes of the seed. | ||||
| */ | ||||
| void randomx_init_cache(randomx_cache *cache, const void *seed, size_t seedSize); | ||||
| 
 | ||||
| /**
 | ||||
|  * Releases all memory occupied by the randomx_cache structure. | ||||
|  * | ||||
|  * @param cache is a pointer to a previously allocated randomx_cache structure. | ||||
| */ | ||||
| void randomx_release_cache(randomx_cache* cache); | ||||
| 
 | ||||
| /**
 | ||||
|  * Creates a randomx_dataset structure and allocates memory for RandomX Dataset. | ||||
|  * | ||||
|  * @param flags is the initialization flags. Only one flag is supported (can be set or not set): | ||||
|  *        RANDOMX_FLAG_LARGE_PAGES - allocate memory in large pages | ||||
| 
 | ||||
|  * @return Pointer to an allocated randomx_cache structure. | ||||
| 		   NULL is returned if memory allocation fails. | ||||
|  */ | ||||
| randomx_dataset *randomx_alloc_dataset(randomx_flags flags); | ||||
| void randomx_init_dataset(randomx_dataset *dataset, randomx_cache *cache, unsigned long startBlock, unsigned long blockCount); | ||||
| 
 | ||||
| /**
 | ||||
|  * Initializes dataset items. | ||||
|  * | ||||
|  * Note: In order to use the Dataset, all items from 0 to (RANDOMX_DATASET_ITEMS - 1) must be initialized. | ||||
|  * This may be done by several calls to this function using non-overlapping item sequences. | ||||
|  * | ||||
|  * @param dataset is a pointer to a previously allocated randomx_dataset structure. Must not be NULL. | ||||
|  * @param cache is a pointer to a previously allocated and initialized randomx_cache structure. Must not be NULL. | ||||
|  * @param startItem is the item number where intialization should start. | ||||
|  * @param itemCount is the number of items that should be initialized. | ||||
| */ | ||||
| void randomx_init_dataset(randomx_dataset *dataset, randomx_cache *cache, unsigned long startItem, unsigned long itemCount); | ||||
| 
 | ||||
| /**
 | ||||
|  * Releases all memory occupied by the randomx_dataset structure. | ||||
|  * | ||||
|  * @param dataset is a pointer to a previously allocated randomx_dataset structure. | ||||
| */ | ||||
| void randomx_release_dataset(randomx_dataset *dataset); | ||||
| 
 | ||||
| /**
 | ||||
|  * Creates and initializes a RandomX virtual machine. | ||||
|  * | ||||
|  * @param flags is any combination of these 4 flags (each flag can be set or not set): | ||||
|  *        RANDOMX_FLAG_LARGE_PAGES - allocate scratchpad memory in large pages | ||||
|  *        RANDOMX_FLAG_HARD_AES - virtual machine will use hardware accelerated AES | ||||
|  *        RANDOMX_FLAG_FULL_MEM - virtual machine will use the full dataset | ||||
|  *        RANDOMX_FLAG_JIT - virtual machine will use a JIT compiler | ||||
|  *        The numeric values of the flags are ordered so that a higher value will provide | ||||
|  *        faster hash calculation and a lower numeric value will provide higher portability. | ||||
|  *        Using RANDOMX_FLAG_DEFAULT (all flags not set) works on all platforms, but is the slowest. | ||||
|  * @param cache is a pointer to an initialized randomx_cache structure. Can be | ||||
|  *        NULL if RANDOMX_FLAG_FULL_MEM is set. | ||||
|  * @param dataset is a pointer to a randomx_dataset structure. Can be NULL | ||||
|  *        if RANDOMX_FLAG_FULL_MEM is not set. | ||||
|  * | ||||
|  * @return Pointer to an initialized randomx_vm structure. | ||||
|  *         Returns NULL if: | ||||
|  *         (1) Scratchpad memory allocation fails. | ||||
|  *         (2) The requested initialization flags are not supported on the current platform. | ||||
|  *         (3) cache parameter is NULL and RANDOMX_FLAG_FULL_MEM is not set | ||||
|  *         (4) dataset parameter is NULL and RANDOMX_FLAG_FULL_MEM is set | ||||
| */ | ||||
| randomx_vm *randomx_create_vm(randomx_flags flags, randomx_cache *cache, randomx_dataset *dataset); | ||||
| 
 | ||||
| /**
 | ||||
|  * Reinitializes a virtual machine with a new Cache. This function should be called anytime | ||||
|  * the Cache is reinitialized with a new seed. | ||||
|  * | ||||
|  * @param machine is a pointer to a randomx_vm structure that was initialized | ||||
|  *        without RANDOMX_FLAG_FULL_MEM. Must not be NULL. | ||||
|  * @param cache is a pointer to an initialized randomx_cache structure. Must not be NULL. | ||||
| */ | ||||
| void randomx_vm_set_cache(randomx_vm *machine, randomx_cache* cache); | ||||
| 
 | ||||
| /**
 | ||||
|  * Reinitializes a virtual machine with a new Dataset. | ||||
|  * | ||||
|  * @param machine is a pointer to a randomx_vm structure that was initialized | ||||
|  *        with RANDOMX_FLAG_FULL_MEM. Must not be NULL. | ||||
|  * @param dataset is a pointer to an initialized randomx_dataset structure. Must not be NULL. | ||||
| */ | ||||
| void randomx_vm_set_dataset(randomx_vm *machine, randomx_dataset *dataset); | ||||
| 
 | ||||
| /**
 | ||||
|  * Releases all memory occupied by the randomx_vm structure. | ||||
|  * | ||||
|  * @param machine is a pointer to a previously created randomx_vm structure. | ||||
| */ | ||||
| void randomx_destroy_vm(randomx_vm *machine); | ||||
| 
 | ||||
| /**
 | ||||
|  * Calculates a RandomX hash value. | ||||
|  * | ||||
|  * @param machine is a pointer to a randomx_vm structure. Must not be NULL. | ||||
|  * @param input is a pointer to memory to be hashed. Must not be NULL. | ||||
|  * @param inputSize is the number of bytes to be hashed. | ||||
|  * @param output is a pointer to memory where the hash will be stored. Must not | ||||
|  *        be NULL and at least RANDOMX_HASH_SIZE bytes must be available for writing. | ||||
| */ | ||||
| void randomx_calculate_hash(randomx_vm *machine, const void *input, size_t inputSize, void *output); | ||||
| 
 | ||||
| #if defined(__cplusplus) | ||||
|  |  | |||
|  | @ -20,8 +20,8 @@ int main() { | |||
| 		std::cout << "Dataset allocation failed" << std::endl; | ||||
| 		return 1; | ||||
| 	} | ||||
| 	std::thread t1(&randomx_init_dataset, myDataset, myCache, 0, RANDOMX_DATASET_BLOCKS / 2); | ||||
| 	std::thread t2(&randomx_init_dataset, myDataset, myCache, RANDOMX_DATASET_BLOCKS / 2, RANDOMX_DATASET_BLOCKS / 2); | ||||
| 	std::thread t1(&randomx_init_dataset, myDataset, myCache, 0, RANDOMX_DATASET_ITEMS / 2); | ||||
| 	std::thread t2(&randomx_init_dataset, myDataset, myCache, RANDOMX_DATASET_ITEMS / 2, RANDOMX_DATASET_ITEMS / 2); | ||||
| 	t1.join(); | ||||
| 	t2.join(); | ||||
| 	randomx_release_cache(myCache); | ||||
|  |  | |||
|  | @ -30,8 +30,6 @@ along with RandomX.  If not, see<http://www.gnu.org/licenses/>. | |||
| #include "../randomx.h" | ||||
| #include "../blake2/endian.h" | ||||
| 
 | ||||
| const uint8_t seed[32] = { 191, 182, 222, 175, 249, 89, 134, 104, 241, 68, 191, 62, 162, 166, 61, 64, 123, 191, 227, 193, 118, 60, 188, 53, 223, 133, 175, 24, 123, 230, 55, 74 }; | ||||
| 
 | ||||
| const uint8_t blockTemplate_[] = { | ||||
| 		0x07, 0x07, 0xf7, 0xa4, 0xf0, 0xd6, 0x05, 0xb3, 0x03, 0x26, 0x08, 0x16, 0xba, 0x3f, 0x10, 0x90, 0x2e, 0x1a, 0x14, | ||||
| 		0x5a, 0xc5, 0xfa, 0xd3, 0xaa, 0x3a, 0xf6, 0xea, 0x44, 0xc1, 0x18, 0x69, 0xdc, 0x4f, 0x85, 0x3f, 0x00, 0x2b, 0x2e, | ||||
|  | @ -82,6 +80,7 @@ void printUsage(const char* executable) { | |||
| 	std::cout << "  --threads T   use T threads (default: 1)" << std::endl; | ||||
| 	std::cout << "  --init Q      initialize dataset with Q threads (default: 1)" << std::endl; | ||||
| 	std::cout << "  --nonces N    run N nonces (default: 1000)" << std::endl; | ||||
| 	std::cout << "  --seed S      seed for cache initialization (default: 0)" << std::endl; | ||||
| } | ||||
| 
 | ||||
| void mine(randomx_vm* vm, std::atomic<uint32_t>& atomicNonce, AtomicHash& result, uint32_t noncesCount, int thread) { | ||||
|  | @ -102,6 +101,7 @@ void mine(randomx_vm* vm, std::atomic<uint32_t>& atomicNonce, AtomicHash& result | |||
| int main(int argc, char** argv) { | ||||
| 	bool softAes, miningMode, verificationMode, help, largePages, jit; | ||||
| 	int noncesCount, threadCount, initThreadCount; | ||||
| 	int32_t seed; | ||||
| 
 | ||||
| 	readOption("--softAes", argc, argv, softAes); | ||||
| 	readOption("--mine", argc, argv, miningMode); | ||||
|  | @ -109,6 +109,7 @@ int main(int argc, char** argv) { | |||
| 	readIntOption("--threads", argc, argv, threadCount, 1); | ||||
| 	readIntOption("--nonces", argc, argv, noncesCount, 1000); | ||||
| 	readIntOption("--init", argc, argv, initThreadCount, 1); | ||||
| 	readIntOption("--seed", argc, argv, seed, 0); | ||||
| 	readOption("--largePages", argc, argv, largePages); | ||||
| 	readOption("--jit", argc, argv, jit); | ||||
| 	readOption("--help", argc, argv, help); | ||||
|  | @ -172,7 +173,7 @@ int main(int argc, char** argv) { | |||
| 			std::cout << "ERROR: Cache allocation failed" << std::endl; | ||||
| 			return 1; | ||||
| 		} | ||||
| 		randomx_init_cache(cache, seed, sizeof(seed)); | ||||
| 		randomx_init_cache(cache, &seed, sizeof(seed)); | ||||
| 		if (miningMode) { | ||||
| 			dataset = randomx_alloc_dataset(flags); | ||||
| 			if (dataset == nullptr) { | ||||
|  | @ -180,20 +181,20 @@ int main(int argc, char** argv) { | |||
| 				return 1; | ||||
| 			} | ||||
| 			if (initThreadCount > 1) { | ||||
| 				auto perThread = RANDOMX_DATASET_BLOCKS / initThreadCount; | ||||
| 				auto remainder = RANDOMX_DATASET_BLOCKS % initThreadCount; | ||||
| 				uint32_t startBlock = 0; | ||||
| 				auto perThread = RANDOMX_DATASET_ITEMS / initThreadCount; | ||||
| 				auto remainder = RANDOMX_DATASET_ITEMS % initThreadCount; | ||||
| 				uint32_t startItem = 0; | ||||
| 				for (int i = 0; i < initThreadCount; ++i) { | ||||
| 					auto count = perThread + (i == initThreadCount - 1 ? remainder : 0); | ||||
| 					threads.push_back(std::thread(&randomx_init_dataset, dataset, cache, startBlock, count)); | ||||
| 					startBlock += count; | ||||
| 					threads.push_back(std::thread(&randomx_init_dataset, dataset, cache, startItem, count)); | ||||
| 					startItem += count; | ||||
| 				} | ||||
| 				for (unsigned i = 0; i < threads.size(); ++i) { | ||||
| 					threads[i].join(); | ||||
| 				} | ||||
| 			} | ||||
| 			else { | ||||
| 				randomx_init_dataset(dataset, cache, 0, RANDOMX_DATASET_BLOCKS); | ||||
| 				randomx_init_dataset(dataset, cache, 0, RANDOMX_DATASET_ITEMS); | ||||
| 			} | ||||
| 			randomx_release_cache(cache); | ||||
| 			threads.clear(); | ||||
|  | @ -227,8 +228,8 @@ int main(int argc, char** argv) { | |||
| 		double elapsed = sw.getElapsed(); | ||||
| 		std::cout << "Calculated result: "; | ||||
| 		result.print(std::cout); | ||||
| 		if (noncesCount == 1000) | ||||
| 			std::cout << "Reference result:  dc34604eed2fbba0e8fae26b2270b90d8aad9466ba39950fd8904248442e850a" << std::endl; | ||||
| 		if (noncesCount == 1000 && seed == 0) | ||||
| 			std::cout << "Reference result:  b69741719152625854031c2337ceae68c3030f2b9581a73acebaa69fc9b555fc" << std::endl; | ||||
| 		if (!miningMode) { | ||||
| 			std::cout << "Performance: " << 1000 * elapsed / noncesCount << " ms per hash" << std::endl; | ||||
| 		} | ||||
|  |  | |||
|  | @ -31,10 +31,10 @@ namespace randomx { | |||
| 
 | ||||
| 	template<class Allocator, bool softAes> | ||||
| 	void InterpretedLightVm<Allocator, softAes>::datasetRead(uint32_t address, int_reg_t(&r)[8]) { | ||||
| 		uint32_t blockNumber = address / CacheLineSize; | ||||
| 		uint32_t itemNumber = address / CacheLineSize; | ||||
| 		int_reg_t rl[8]; | ||||
| 		 | ||||
| 		initDatasetBlock(cachePtr, (uint8_t*)rl, blockNumber); | ||||
| 		initDatasetItem(cachePtr, (uint8_t*)rl, itemNumber); | ||||
| 
 | ||||
| 		for (unsigned q = 0; q < 8; ++q) | ||||
| 			r[q] ^= rl[q]; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue