Make DqnRnd a class, make array memapi aware
This commit is contained in:
		
							parent
							
								
									25098ca74c
								
							
						
					
					
						commit
						2f6624fad7
					
				
							
								
								
									
										71
									
								
								dqn.h
									
									
									
									
									
								
							
							
						
						
									
										71
									
								
								dqn.h
									
									
									
									
									
								
							| @ -540,6 +540,7 @@ template <typename T> | |||||||
| bool DqnArray<T>::Resize(i64 newMax) | bool DqnArray<T>::Resize(i64 newMax) | ||||||
| { | { | ||||||
| 	if (!this->data)            return false; | 	if (!this->data)            return false; | ||||||
|  | 	if (!this->memAPI.callback) return false; | ||||||
| 
 | 
 | ||||||
| 	i64 oldSize = this->max * sizeof(T); | 	i64 oldSize = this->max * sizeof(T); | ||||||
| 	i64 newSize = newMax * sizeof(T); | 	i64 newSize = newMax * sizeof(T); | ||||||
| @ -1468,22 +1469,18 @@ DQN_FILE_SCOPE i32  Dqn_I32ToWStr(i32 value, wchar_t *buf, i32 bufSize); | |||||||
| // #DqnRnd Public API - Random Number Generator
 | // #DqnRnd Public API - Random Number Generator
 | ||||||
| ////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////
 | ||||||
| // PCG (Permuted Congruential Generator) Random Number Generator
 | // PCG (Permuted Congruential Generator) Random Number Generator
 | ||||||
| typedef struct DqnRandPCGState | class DqnRndPCG | ||||||
| { | { | ||||||
|  | public: | ||||||
| 	u64 state[2]; | 	u64 state[2]; | ||||||
| } DqnRandPCGState; |  | ||||||
| 
 | 
 | ||||||
| // pcg: Pass in a pointer to a zero-cleared DqnRandPCGState
 | 	void Init        ();          // Uses rdstc to create a seed
 | ||||||
| DQN_FILE_SCOPE void DqnRnd_PCGInitWithSeed(DqnRandPCGState *pcg, u32 seed); | 	void InitWithSeed(u32 seed); | ||||||
| // Uses __rdtsc() to create a seed. TODO(doyle): This requires the platform layer.
 |  | ||||||
| DQN_FILE_SCOPE void DqnRnd_PCGInit(DqnRandPCGState *pcg); |  | ||||||
| 
 | 
 | ||||||
| // return: A random number N between [0, 0xFFFFFFFF]
 | 	u32 Next ();                 // return: A random number  N between [0, 0xFFFFFFFF]
 | ||||||
| DQN_FILE_SCOPE u32  DqnRnd_PCGNext (DqnRandPCGState *pcg); | 	f32 Nextf();                 // return: A random float   N between [0.0, 1.0f]
 | ||||||
| // return: A random float N between [0.0, 1.0f]
 | 	i32 Range(i32 min, i32 max); // return: A random integer N between [min, max]
 | ||||||
| DQN_FILE_SCOPE f32  DqnRnd_PCGNextf(DqnRandPCGState *pcg); | }; | ||||||
| // return: A random integer N between [min, max]
 |  | ||||||
| DQN_FILE_SCOPE i32  DqnRnd_PCGRange(DqnRandPCGState *pcg, i32 min, i32 max); |  | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////
 | ||||||
| // #Dqn_* Public API
 | // #Dqn_* Public API
 | ||||||
| @ -1525,11 +1522,10 @@ DQN_FILE_SCOPE void Dqn_QuickSort(T *const array, const i32 size, | |||||||
| 	} | 	} | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 	DqnRandPCGState state = {}; | 	DqnRndPCG state; state.Init(); | ||||||
| 	DqnRnd_PCGInit(&state); |  | ||||||
| 
 | 
 | ||||||
| 	i32 lastIndex      = size - 1; | 	i32 lastIndex      = size - 1; | ||||||
| 	i32 pivotIndex     = DqnRnd_PCGRange(&state, 0, lastIndex); | 	i32 pivotIndex     = state.Range(0, lastIndex); | ||||||
| 	i32 partitionIndex = 0; | 	i32 partitionIndex = 0; | ||||||
| 	i32 startIndex     = 0; | 	i32 startIndex     = 0; | ||||||
| 
 | 
 | ||||||
| @ -5169,7 +5165,7 @@ union DqnRndInternal_U32F32 | |||||||
| 	f32 float32; | 	f32 float32; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| FILE_SCOPE f32 DqnRnd_F32NormalizedFromU32Internal(u32 value) | FILE_SCOPE f32 DqnRndInternal_F32NormalizedFromU32(u32 value) | ||||||
| { | { | ||||||
| 	u32 exponent = 127; | 	u32 exponent = 127; | ||||||
| 	u32 mantissa = value >> 9; | 	u32 mantissa = value >> 9; | ||||||
| @ -5179,7 +5175,7 @@ FILE_SCOPE f32 DqnRnd_F32NormalizedFromU32Internal(u32 value) | |||||||
| 	return uf.float32 - 1.0f; | 	return uf.float32 - 1.0f; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| FILE_SCOPE u64 DqnRnd_Murmur3Avalanche64Internal(u64 h) | FILE_SCOPE u64 DqnRndInternal_Murmur3Avalanche64(u64 h) | ||||||
| { | { | ||||||
| 	h ^= h >> 33; | 	h ^= h >> 33; | ||||||
| 	h *= 0xff51afd7ed558ccd; | 	h *= 0xff51afd7ed558ccd; | ||||||
| @ -5193,7 +5189,7 @@ FILE_SCOPE u64 DqnRnd_Murmur3Avalanche64Internal(u64 h) | |||||||
| 	#include <x86intrin.h> // __rdtsc | 	#include <x86intrin.h> // __rdtsc | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| FILE_SCOPE u32 DqnRnd_MakeSeedInternal() | FILE_SCOPE u32 DqnRndInternal_MakeSeed() | ||||||
| { | { | ||||||
| #if defined(DQN_WIN32_PLATFORM) || defined(DQN_UNIX_PLATFORM) | #if defined(DQN_WIN32_PLATFORM) || defined(DQN_UNIX_PLATFORM) | ||||||
| 	i64 numClockCycles = __rdtsc(); | 	i64 numClockCycles = __rdtsc(); | ||||||
| @ -5207,43 +5203,46 @@ FILE_SCOPE u32 DqnRnd_MakeSeedInternal() | |||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| DQN_FILE_SCOPE void DqnRnd_PCGInitWithSeed(DqnRandPCGState *pcg, u32 seed) | void DqnRndPCG::InitWithSeed(u32 seed) | ||||||
| { | { | ||||||
| 	u64 value     = (((u64)seed) << 1ULL) | 1ULL; | 	u64 value     = (((u64)seed) << 1ULL) | 1ULL; | ||||||
| 	value         = DqnRnd_Murmur3Avalanche64Internal(value); | 	value         = DqnRndInternal_Murmur3Avalanche64(value); | ||||||
| 	pcg->state[0] = 0U; | 	this->state[0] = 0U; | ||||||
| 	pcg->state[1] = (value << 1ULL) | 1ULL; | 	this->state[1] = (value << 1ULL) | 1ULL; | ||||||
| 	DqnRnd_PCGNext(pcg); | 	this->Next(); | ||||||
| 	pcg->state[0] += DqnRnd_Murmur3Avalanche64Internal(value); | 	this->state[0] += DqnRndInternal_Murmur3Avalanche64(value); | ||||||
| 	DqnRnd_PCGNext(pcg); | 	this->Next(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| DQN_FILE_SCOPE void DqnRnd_PCGInit(DqnRandPCGState *pcg) | void DqnRndPCG::Init() | ||||||
| { | { | ||||||
| 	u32 seed = DqnRnd_MakeSeedInternal(); | 	u32 seed = DqnRndInternal_MakeSeed(); | ||||||
| 	DqnRnd_PCGInitWithSeed(pcg, seed); | 	this->InitWithSeed(seed); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| DQN_FILE_SCOPE u32 DqnRnd_PCGNext(DqnRandPCGState *pcg) | u32 DqnRndPCG::Next() | ||||||
| { | { | ||||||
| 	u64 oldstate   = pcg->state[0]; | 	u64 oldstate   = this->state[0]; | ||||||
| 	pcg->state[0]  = oldstate * 0x5851f42d4c957f2dULL + pcg->state[1]; | 	this->state[0] = oldstate * 0x5851f42d4c957f2dULL + this->state[1]; | ||||||
| 	u32 xorshifted = (u32)(((oldstate >> 18ULL) ^ oldstate) >> 27ULL); | 	u32 xorshifted = (u32)(((oldstate >> 18ULL) ^ oldstate) >> 27ULL); | ||||||
| 	u32 rot        = (u32)(oldstate >> 59ULL); | 	u32 rot        = (u32)(oldstate >> 59ULL); | ||||||
| 	return (xorshifted >> rot) | (xorshifted << ((-(i32)rot) & 31)); | 	return (xorshifted >> rot) | (xorshifted << ((-(i32)rot) & 31)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| DQN_FILE_SCOPE f32 DqnRnd_PCGNextf(DqnRandPCGState *pcg) | f32 DqnRndPCG::Nextf() | ||||||
| { | { | ||||||
| 	return DqnRnd_F32NormalizedFromU32Internal(DqnRnd_PCGNext(pcg)); | 	f32 result = DqnRndInternal_F32NormalizedFromU32(this->Next()); | ||||||
|  | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| DQN_FILE_SCOPE i32 DqnRnd_PCGRange(DqnRandPCGState *pcg, i32 min, i32 max) | i32 DqnRndPCG::Range(i32 min, i32 max) | ||||||
| { | { | ||||||
| 	i32 const range = (max - min) + 1; | 	i32 const range = (max - min) + 1; | ||||||
| 	if (range <= 0) return min; | 	if (range <= 0) return min; | ||||||
| 	i32 const value = (i32)(DqnRnd_PCGNextf(pcg) * range); | 
 | ||||||
| 	return min + value; | 	i32 const value = (i32)(this->Nextf() * range); | ||||||
|  | 	i32 result      = min + value; | ||||||
|  | 	return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////
 | ||||||
|  | |||||||
| @ -641,18 +641,19 @@ void DqnTimer_Test() | |||||||
| void DqnRnd_Test() | void DqnRnd_Test() | ||||||
| { | { | ||||||
| 	LogHeader("Random Number Generator Test"); | 	LogHeader("Random Number Generator Test"); | ||||||
| 	DqnRandPCGState pcg; | 
 | ||||||
| 	DqnRnd_PCGInit(&pcg); | 	DqnRndPCG pcg; pcg.Init(); | ||||||
| 	for (i32 i = 0; i < 1000000; i++) | 	for (i32 i = 0; i < 1000000; i++) | ||||||
| 	{ | 	{ | ||||||
| 		i32 min    = -100; | 		i32 min    = -100; | ||||||
| 		i32 max    = 1000000000; | 		i32 max    = 1000000000; | ||||||
| 		i32 result = DqnRnd_PCGRange(&pcg, min, max); | 		i32 result = pcg.Range(min, max); | ||||||
| 		DQN_ASSERT(result >= min && result <= max); | 		DQN_ASSERT(result >= min && result <= max); | ||||||
| 
 | 
 | ||||||
| 		f32 randF32 = DqnRnd_PCGNextf(&pcg); | 		f32 randF32 = pcg.Nextf(); | ||||||
| 		DQN_ASSERT(randF32 >= 0.0f && randF32 <= 1.0f); | 		DQN_ASSERT(randF32 >= 0.0f && randF32 <= 1.0f); | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
| 	printf("RandomTest(): RndPCG: Completed successfully\n"); | 	printf("RandomTest(): RndPCG: Completed successfully\n"); | ||||||
| 	printf("RandomTest(): Completed successfully\n"); | 	printf("RandomTest(): Completed successfully\n"); | ||||||
| } | } | ||||||
| @ -1992,8 +1993,7 @@ FILE_SCOPE void DqnJobQueue_Test() | |||||||
| void DqnQuickSort_Test() | void DqnQuickSort_Test() | ||||||
| { | { | ||||||
| 	LogHeader("DqnSort vs std::Sort"); | 	LogHeader("DqnSort vs std::Sort"); | ||||||
| 	DqnRandPCGState state = {}; | 	DqnRndPCG state; state.Init(); | ||||||
| 	DqnRnd_PCGInit(&state); |  | ||||||
| 	if (1) | 	if (1) | ||||||
| 	{ | 	{ | ||||||
| 		DqnMemStack stack = {}; | 		DqnMemStack stack = {}; | ||||||
| @ -2017,7 +2017,7 @@ void DqnQuickSort_Test() | |||||||
| 			// Populate with random numbers
 | 			// Populate with random numbers
 | ||||||
| 			for (u32 i = 0; i < numInts; i++) | 			for (u32 i = 0; i < numInts; i++) | ||||||
| 			{ | 			{ | ||||||
| 				dqnCPPArray[i] = DqnRnd_PCGNext(&state); | 				dqnCPPArray[i] = state.Next(); | ||||||
| 				stdArray[i]    = dqnCPPArray[i]; | 				stdArray[i]    = dqnCPPArray[i]; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user