Added a method to GPrng to get a random uint32, which is about twice as fast as GetRandom<uint32_t>

This commit is contained in:
Leonetienne 2022-05-26 12:52:04 +02:00
parent e9377699f2
commit 800140bafa
No known key found for this signature in database
GPG Key ID: C33879CD92E9708C
2 changed files with 49 additions and 0 deletions

View File

@ -46,6 +46,9 @@ namespace Leonetienne::GCrypt {
return t; return t;
} }
//! Will return a random unsigned 32-bit integer
std::uint32_t operator()();
//! Will return a random block //! Will return a random block
Block GetBlock(); Block GetBlock();

View File

@ -53,6 +53,10 @@ namespace Leonetienne::GCrypt {
// We don't even have to AdvanceBlock(), because we've only given out // We don't even have to AdvanceBlock(), because we've only given out
// hashsum', not hashsum. // hashsum', not hashsum.
// Performance improvement over the previous method:
// (generating 100.000 blocks):
// 12 seconds -> 0.12 seconds
// Fetch our current block // Fetch our current block
Block hashsum = hasher.GetHashsum(); Block hashsum = hasher.GetHashsum();
@ -65,5 +69,47 @@ namespace Leonetienne::GCrypt {
return hashsum; return hashsum;
} }
std::uint32_t GPrng::operator()() {
// Tactic:
// A block intrinsically consists of 16 32-bit uints.
// We'll just skip all the bits until the next whole integer,
// fetch this complete int, and then advance our pointer
// by 32 bits.
// Performance improvement over the previous method:
// (generating 1.000.000 integers):
// 5.26 seconds -> 3.84 seconds
// Advance our pointer to the next whole uint32
// Do we even have >= 32 bits left in our block?
if (nextBit > Block::BLOCK_SIZE_BITS - Block::CHUNK_SIZE_BITS) {
// No: Create a new block
AdvanceBlock();
}
// We don't have to do this, if our pointer is already at
// the beginning of a whole uint32
if (nextBit % Block::CHUNK_SIZE_BITS != 0) {
nextBit = ((nextBit / Block::CHUNK_SIZE_BITS) + 1) * Block::CHUNK_SIZE_BITS;
}
// Fetch our integer from the block
const std::uint32_t randint =
hasher.GetHashsum().Get(nextBit / Block::CHUNK_SIZE_BITS);
// Advance our pointer
nextBit += Block::CHUNK_SIZE_BITS;
// New state of the pointer:
// It ow may be more now than the size of a block, but that
// gets checked at the begin of a function.
// Not at the end, like here.
// Return our integer
return randint;
}
} }