Simplify DqnRndPCG
This commit is contained in:
parent
0bf1b6d3ff
commit
5dee3d9f89
@ -709,7 +709,7 @@ void DqnRnd_Test()
|
|||||||
{
|
{
|
||||||
LOG_HEADER();
|
LOG_HEADER();
|
||||||
|
|
||||||
DqnRndPCG pcg; pcg.Init();
|
auto pcg = DqnRndPCG();
|
||||||
for (i32 i = 0; i < 1000000; i++)
|
for (i32 i = 0; i < 1000000; i++)
|
||||||
{
|
{
|
||||||
i32 min = -100;
|
i32 min = -100;
|
||||||
@ -1932,7 +1932,7 @@ FILE_SCOPE void DqnJobQueue_Test()
|
|||||||
void DqnQuickSort_Test()
|
void DqnQuickSort_Test()
|
||||||
{
|
{
|
||||||
LOG_HEADER();
|
LOG_HEADER();
|
||||||
DqnRndPCG state; state.Init();
|
auto state = DqnRndPCG();
|
||||||
if (1)
|
if (1)
|
||||||
{
|
{
|
||||||
DqnMemStack stack = {};
|
DqnMemStack stack = {};
|
||||||
@ -2247,7 +2247,7 @@ void Dqn_BSearch_Test()
|
|||||||
void DqnMemSet_Test()
|
void DqnMemSet_Test()
|
||||||
{
|
{
|
||||||
LOG_HEADER();
|
LOG_HEADER();
|
||||||
DqnRndPCG rnd = DqnRndPCG_();
|
auto rnd = DqnRndPCG();
|
||||||
|
|
||||||
const int NUM_TIMINGS = 5;
|
const int NUM_TIMINGS = 5;
|
||||||
f64 timings[2][NUM_TIMINGS] = {};
|
f64 timings[2][NUM_TIMINGS] = {};
|
||||||
|
57
dqn.h
57
dqn.h
@ -766,23 +766,18 @@ DQN_FILE_SCOPE i32 Dqn_I32ToWStr (i32 value, wchar_t *buf, i32
|
|||||||
|
|
||||||
// #DqnRnd API
|
// #DqnRnd API
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
// NOTE: Uses PCG (Permuted Congruential Generator)
|
struct DqnRndPCG // PCG (Permuted Congruential Generator)
|
||||||
struct DqnRndPCG
|
|
||||||
{
|
{
|
||||||
u64 state[2];
|
u64 state[2];
|
||||||
|
|
||||||
void Init (); // Uses rdstc to create a seed
|
DqnRndPCG();
|
||||||
void InitWithSeed(u32 seed);
|
DqnRndPCG(u32 seed);
|
||||||
|
|
||||||
u32 Next (); // return: A random number N between [0, 0xFFFFFFFF]
|
u32 Next (); // return: A random number N between [0, 0xFFFFFFFF]
|
||||||
f32 Nextf(); // return: A random float N between [0.0, 1.0f]
|
f32 Nextf(); // return: A random float N between [0.0, 1.0f]
|
||||||
i32 Range(i32 min, i32 max); // return: A random integer N between [min, max]
|
i32 Range(i32 min, i32 max); // return: A random integer N between [min, max]
|
||||||
};
|
};
|
||||||
|
|
||||||
DQN_FILE_SCOPE DqnRndPCG DqnRndPCG_(); // Uses rdtsc to create a seed
|
|
||||||
DQN_FILE_SCOPE DqnRndPCG DqnRndPCG_(u32 seed);
|
|
||||||
|
|
||||||
|
|
||||||
// #Dqn_* API
|
// #Dqn_* API
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
// return: The number of splits in the array. If array is null this returns the required size of the array.
|
// return: The number of splits in the array. If array is null this returns the required size of the array.
|
||||||
@ -835,8 +830,7 @@ DQN_FILE_SCOPE void Dqn_QuickSort(T *array, i64 size,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DqnRndPCG state; state.Init();
|
auto state = DqnRndPCG();
|
||||||
|
|
||||||
auto lastIndex = size - 1;
|
auto lastIndex = size - 1;
|
||||||
auto pivotIndex = (i64)state.Range(0, (i32)lastIndex);
|
auto pivotIndex = (i64)state.Range(0, (i32)lastIndex);
|
||||||
auto partitionIndex = 0;
|
auto partitionIndex = 0;
|
||||||
@ -907,8 +901,7 @@ DQN_FILE_SCOPE void Dqn_QuickSort(T *array, i64 size)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DqnRndPCG state; state.Init();
|
auto state = DqnRndPCG();
|
||||||
|
|
||||||
auto lastIndex = size - 1;
|
auto lastIndex = size - 1;
|
||||||
auto pivotIndex = (i64)state.Range(0, (i32)lastIndex); // TODO(doyle): RNG 64bit
|
auto pivotIndex = (i64)state.Range(0, (i32)lastIndex); // TODO(doyle): RNG 64bit
|
||||||
auto partitionIndex = 0;
|
auto partitionIndex = 0;
|
||||||
@ -5925,23 +5918,23 @@ DQN_FILE_SCOPE i32 Dqn_I32ToWstr(i32 value, wchar_t *buf, i32 bufSize)
|
|||||||
// < 1.0f. Contributed by Jonatan Hedborg
|
// < 1.0f. Contributed by Jonatan Hedborg
|
||||||
|
|
||||||
// NOTE: This is to abide to strict aliasing rules.
|
// NOTE: This is to abide to strict aliasing rules.
|
||||||
union DqnRndInternal_U32F32
|
union DqnRnd__U32F32
|
||||||
{
|
{
|
||||||
u32 unsigned32;
|
u32 unsigned32;
|
||||||
f32 float32;
|
f32 float32;
|
||||||
};
|
};
|
||||||
|
|
||||||
FILE_SCOPE f32 DqnRndInternal_F32NormalizedFromU32(u32 value)
|
FILE_SCOPE f32 DqnRnd__F32NormalizedFromU32(u32 value)
|
||||||
{
|
{
|
||||||
u32 exponent = 127;
|
u32 exponent = 127;
|
||||||
u32 mantissa = value >> 9;
|
u32 mantissa = value >> 9;
|
||||||
|
|
||||||
union DqnRndInternal_U32F32 uf;
|
union DqnRnd__U32F32 uf;
|
||||||
uf.unsigned32 = (exponent << 23 | mantissa);
|
uf.unsigned32 = (exponent << 23 | mantissa);
|
||||||
return uf.float32 - 1.0f;
|
return uf.float32 - 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE_SCOPE u64 DqnRndInternal_Murmur3Avalanche64(u64 h)
|
FILE_SCOPE u64 DqnRnd__Murmur3Avalanche64(u64 h)
|
||||||
{
|
{
|
||||||
h ^= h >> 33;
|
h ^= h >> 33;
|
||||||
h *= 0xff51afd7ed558ccd;
|
h *= 0xff51afd7ed558ccd;
|
||||||
@ -5955,7 +5948,7 @@ FILE_SCOPE u64 DqnRndInternal_Murmur3Avalanche64(u64 h)
|
|||||||
#include <x86intrin.h> // __rdtsc
|
#include <x86intrin.h> // __rdtsc
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FILE_SCOPE u32 DqnRndInternal_MakeSeed()
|
FILE_SCOPE u32 DqnRnd__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();
|
||||||
@ -5969,37 +5962,23 @@ FILE_SCOPE u32 DqnRndInternal_MakeSeed()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE DqnRndPCG DqnRndPCG_()
|
DqnRndPCG::DqnRndPCG()
|
||||||
{
|
{
|
||||||
DqnRndPCG result;
|
u32 seed = DqnRnd__MakeSeed();
|
||||||
result.Init();
|
*this = DqnRndPCG(seed);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DQN_FILE_SCOPE DqnRndPCG DqnRndPCG_(u32 seed)
|
DqnRndPCG::DqnRndPCG(u32 seed)
|
||||||
{
|
{
|
||||||
DqnRndPCG result;
|
u64 value = (((u64)seed) << 1ULL) | 1ULL;
|
||||||
result.InitWithSeed(seed);
|
value = DqnRnd__Murmur3Avalanche64(value);
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DqnRndPCG::InitWithSeed(u32 seed)
|
|
||||||
{
|
|
||||||
u64 value = (((u64)seed) << 1ULL) | 1ULL;
|
|
||||||
value = DqnRndInternal_Murmur3Avalanche64(value);
|
|
||||||
this->state[0] = 0U;
|
this->state[0] = 0U;
|
||||||
this->state[1] = (value << 1ULL) | 1ULL;
|
this->state[1] = (value << 1ULL) | 1ULL;
|
||||||
this->Next();
|
this->Next();
|
||||||
this->state[0] += DqnRndInternal_Murmur3Avalanche64(value);
|
this->state[0] += DqnRnd__Murmur3Avalanche64(value);
|
||||||
this->Next();
|
this->Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DqnRndPCG::Init()
|
|
||||||
{
|
|
||||||
u32 seed = DqnRndInternal_MakeSeed();
|
|
||||||
this->InitWithSeed(seed);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 DqnRndPCG::Next()
|
u32 DqnRndPCG::Next()
|
||||||
{
|
{
|
||||||
u64 oldstate = this->state[0];
|
u64 oldstate = this->state[0];
|
||||||
@ -6011,7 +5990,7 @@ u32 DqnRndPCG::Next()
|
|||||||
|
|
||||||
f32 DqnRndPCG::Nextf()
|
f32 DqnRndPCG::Nextf()
|
||||||
{
|
{
|
||||||
f32 result = DqnRndInternal_F32NormalizedFromU32(this->Next());
|
f32 result = DqnRnd__F32NormalizedFromU32(this->Next());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user