[*] RNG (PLAYBACK ABI-BREAK!!!): preemptively silence the turbo autists that are going to complain about modulo bias
(...well, mostly. this will be good enough.) [*] Improve fast RNG device perf
This commit is contained in:
parent
e3cecc2d35
commit
999f3e69ca
@ -29,19 +29,18 @@ namespace Aurora::RNG
|
||||
{
|
||||
if (def.seed)
|
||||
{
|
||||
this->fast_ = WELL_SeedRand(def.seed.value());
|
||||
this->fast_ = AuMove(WELL_SeedRand(def.seed.value()));
|
||||
}
|
||||
else if (def.seed64)
|
||||
{
|
||||
this->fast_ = WELL_SeedRand64(def.seed64.value());
|
||||
this->fast_ = AuMove(WELL_SeedRand64(def.seed64.value()));
|
||||
}
|
||||
else if (def.seedMassive)
|
||||
{
|
||||
this->fast_ = WELL_SeedRandBig64(def.seedMassive.value());
|
||||
this->fast_ = AuMove(WELL_SeedRandBig64(def.seedMassive.value()));
|
||||
}
|
||||
else
|
||||
{
|
||||
this->fast_ = {};
|
||||
RNG::RngFillArray<false>(this->fast_.state);
|
||||
}
|
||||
}
|
||||
@ -82,7 +81,7 @@ namespace Aurora::RNG
|
||||
{"ABCDEFGHIJKLMNOPQRSTUVWXYZ", 26},
|
||||
{"1234567890", 10},
|
||||
{"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", 62},
|
||||
{"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890=-+!$%^*.[];:", 75}
|
||||
{"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890=-+!!$%^*.[];:", 76}
|
||||
};
|
||||
|
||||
if (!pString)
|
||||
@ -109,34 +108,94 @@ namespace Aurora::RNG
|
||||
|
||||
AuUInt8 RandomDevice::NextByte()
|
||||
{
|
||||
return NextFillTmpl<AuUInt8>();
|
||||
if (this->def_.bSecure)
|
||||
{
|
||||
AuUInt8 uRet {};
|
||||
ReadSecureRNG({ &uRet, 1 });
|
||||
return uRet;
|
||||
}
|
||||
else
|
||||
{
|
||||
return AuUInt8(WELL_NextLong(&this->fast_) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
bool RandomDevice::NextBoolean()
|
||||
{
|
||||
return NextByte() > 127;
|
||||
if (this->def_.bSecure)
|
||||
{
|
||||
AuUInt8 uRet {};
|
||||
ReadSecureRNG({ &uRet, 1 });
|
||||
return bool(uRet & 0x1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return bool(WELL_NextLong(&this->fast_) & 0x1);
|
||||
}
|
||||
}
|
||||
|
||||
AuUInt32 RandomDevice::NextU32()
|
||||
{
|
||||
return NextFillTmpl<AuUInt32>();
|
||||
if (this->def_.bSecure)
|
||||
{
|
||||
AuUInt32 uRet {};
|
||||
ReadSecureRNG({ &uRet, 4 });
|
||||
return uRet;
|
||||
}
|
||||
else
|
||||
{
|
||||
return WELL_NextLong(&this->fast_);
|
||||
}
|
||||
}
|
||||
|
||||
AuUInt64 RandomDevice::NextU64()
|
||||
{
|
||||
if (this->def_.bSecure)
|
||||
{
|
||||
AuUInt64 uRet {};
|
||||
ReadSecureRNG({ &uRet, 8 });
|
||||
return uRet;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NextFillTmpl<AuUInt64>();
|
||||
}
|
||||
}
|
||||
|
||||
AuInt32 RandomDevice::NextInt(AuInt32 uMin, AuInt32 uMax)
|
||||
{
|
||||
#if 0
|
||||
auto range = uMax - uMin;
|
||||
return (NextU64() % range) + uMin;
|
||||
#else
|
||||
auto uRange = uMax - uMin;
|
||||
auto uMassiveWord = NextU32();
|
||||
auto uUpperBound = AuPageRoundUp<AuUInt32>(uRange, 2);
|
||||
AuUInt32 uNext {};
|
||||
while ((uNext = (uMassiveWord & (uUpperBound - 1))) >= uRange)
|
||||
{
|
||||
uMassiveWord = NextU32();
|
||||
}
|
||||
return uMin + uNext;
|
||||
#endif
|
||||
}
|
||||
|
||||
AuUInt32 RandomDevice::NextU32(AuUInt32 uMin, AuUInt32 uMax)
|
||||
{
|
||||
#if 0
|
||||
auto range = uMax - uMin;
|
||||
return (NextU64() % range) + uMin;
|
||||
#else
|
||||
auto uRange = uMax - uMin;
|
||||
auto uMassiveWord = NextU32();
|
||||
auto uUpperBound = AuPageRoundUp<AuUInt32>(uRange, 2);
|
||||
AuUInt32 uNext {};
|
||||
while ((uNext = (uMassiveWord & (uUpperBound - 1))) >= uRange)
|
||||
{
|
||||
uMassiveWord = NextU32();
|
||||
}
|
||||
return uMin + uNext;
|
||||
#endif
|
||||
}
|
||||
|
||||
double RandomDevice::NextDecimal()
|
||||
@ -146,13 +205,24 @@ namespace Aurora::RNG
|
||||
|
||||
AuUInt32 RandomDevice::NextIndex(AuUInt32 uCount /* = max + 1*/)
|
||||
{
|
||||
#if 0
|
||||
return NextU32() % uCount;
|
||||
#else
|
||||
auto uMassiveWord = NextU32();
|
||||
auto uUpperBound = AuPageRoundUp<AuUInt32>(uCount, 2);
|
||||
AuUInt32 uNext {};
|
||||
while ((uNext = (uMassiveWord & (uUpperBound - 1))) >= uCount)
|
||||
{
|
||||
uMassiveWord = NextU32();
|
||||
}
|
||||
return uNext;
|
||||
#endif
|
||||
}
|
||||
|
||||
float RandomDevice::NextNumber(float min, float max)
|
||||
float RandomDevice::NextNumber(float fMin, float fMax)
|
||||
{
|
||||
auto range = max - min;
|
||||
return NextDecimal() * range + min;
|
||||
auto fRange = fMax - fMin;
|
||||
return NextDecimal() * fRange + fMin;
|
||||
}
|
||||
|
||||
AuMemoryViewRead RandomDevice::ToSeed()
|
||||
|
@ -49,26 +49,26 @@ static auline void WELL_SeedRand(WELLRand *rand, AuUInt32 seed)
|
||||
/**
|
||||
* Creates a new random number generator from a given seed.
|
||||
*/
|
||||
WELLRand WELL_SeedRand(AuUInt32 seed)
|
||||
WELLRand &&WELL_SeedRand(AuUInt32 seed)
|
||||
{
|
||||
WELLRand rand {};
|
||||
WELL_SeedRand(&rand, seed);
|
||||
return rand;
|
||||
return AuMove(rand);
|
||||
}
|
||||
|
||||
WELLRand WELL_SeedRand64(AuUInt64 seed)
|
||||
WELLRand &&WELL_SeedRand64(AuUInt64 seed)
|
||||
{
|
||||
WELLRand rand {};
|
||||
WELL_SeedRand64(&rand, seed);
|
||||
return rand;
|
||||
return AuMove(rand);
|
||||
}
|
||||
|
||||
WELLRand WELL_SeedRandBig64(const AuArray<AuUInt8, 64> &seed)
|
||||
WELLRand &&WELL_SeedRandBig64(const AuArray<AuUInt8, 64> &seed)
|
||||
{
|
||||
WELLRand rand {};
|
||||
static_assert(64 == sizeof(rand.state));
|
||||
AuMemcpy(rand.state, seed.data(), sizeof(rand.state));
|
||||
return rand;
|
||||
return AuMove(rand);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,12 +3,19 @@
|
||||
struct WELLRand
|
||||
{
|
||||
AuUInt32 state[16];
|
||||
int index;
|
||||
AuThreadPrimitives::SpinLock lock;
|
||||
int index {};
|
||||
AuFutexMutex lock;
|
||||
|
||||
inline WELLRand &operator =(WELLRand &&rand)
|
||||
{
|
||||
AuMemcpy(this->state, rand.state, sizeof(this->state));
|
||||
this->index = rand.index;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
WELLRand WELL_SeedRand(AuUInt32 seed);
|
||||
WELLRand WELL_SeedRandBig64(const AuArray<AuUInt8, 64> &seed);
|
||||
WELLRand WELL_SeedRand64(AuUInt64 seed);
|
||||
WELLRand &&WELL_SeedRand(AuUInt32 seed);
|
||||
WELLRand &&WELL_SeedRandBig64(const AuArray<AuUInt8, 64> &seed);
|
||||
WELLRand &&WELL_SeedRand64(AuUInt64 seed);
|
||||
AuUInt32 WELL_NextLong(WELLRand* rand);
|
||||
void WELL_NextBytes(WELLRand *rand, void *in, AuUInt32 length);
|
Loading…
Reference in New Issue
Block a user