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…
Reference in New Issue
Block a user