Many, if not all, generators need to be warmed up. What happens is that during the early stages of generation the random numbers are not that random and should be avoided. The easiest way to avoid them is to 'burn' a sufficient number until we reach a stage where the random numbers are better quality. With some generators, we don't need to 'burn' that many - with others we need to 'burn' quite a few.
A lot of code on the forum uses random numbers at the beginning of the code for initialization purposes only. Many folk will not realize that the numbers generated may not be of good quality even though the generator they are using is known for good quality random numbers.
With PractRand it examines blocks of data and the early numbers may not be a large enough sample for PractRand to reject the generator.
So, how do we know when we have reached a stage where the random numbers are better quality. This occurs when the original seed, after updating, tends to have a balance of zeros and ones. What we have is a Hamming weighting of 50%.
Instead of warming up we can ensure that the original seed has a good Hamming weight to start with.
When the generator is running the Hamming weight will drift in and out of a good state. There is nothing we can do about that - that is random numbers. However, according to the normal distribution, we shouldn't find ourselves in a poor state for long. If that happened PractRand would jump in and reject the generator.
The following code is one way of ensuring that a seed has a good Hamming weight.
Code: Select all
Function RdtscSeed() As Ulong
Dim Seed As Ulong
Asm
0:
rdtsc ' Get a fast changing number from the processor
bswap eax ' Reverse byte order to break sequence
popcnt edx, eax ' Count the number of set bits in eax
cmp edx, 14 ' Force a good entropy with a Hamming Weight of 14 or more
jl 0b
cmp edx, 18 ' Force a good entropy with a Hamming Weight of 18 or less
jg 0b
mov Dword Ptr [Seed], eax
End Asm
Return Seed
End Function
rdtsc gives us 2^32 possible values. Staying in the code until we are in a good entropy window gives us 2^27*5 possible values, 671,088,640. That plus reversing the byte order will ensure that no one will be able to guess the seed generated anytime soon.
The time to come up with a suitable seed will vary. I tested RdtscSeed 100 million times and the longest time taken was 175 microseconds, so we shouldn't find ourselves twiddling our thumbs waiting. That test took over three minutes to complete.
Now for a graphics program using a dozen or so random ranges during initialization may see them as having exceptionally poor quality. This may not be an issue. On the other hand it may be. So if you use the FB generators using RdtscSeed should ensure that you get decent quality random numbers from the word go.
Not a great deal of work has been done on warming up generators. Here is a graph published by Sebastiano Vigna a few years back. As can be seen from this small sample warming up does not take that long and generators with large state vectors tend to take longer. We cannot second guess how long a particular generator will take to warm up but RdtscSeed solves that problem for us.