Boost logo

Boost :

From: Greg Colvin (gcolvin_at_[hidden])
Date: 2000-02-20 21:43:57


From: Jacob Hammeken <jacobh_at_[hidden]>
> Greg Colvin wrote:
> > I've been playing around with this, and made a small modification
> > so that you can vary the quality of the result by specifying nbits
> > other than 8. Also made it compile as C (:-)
> ...
> > I didn't mask off the higher bits of the counter
> ...
> > I also made a Win32-specific version that has the virtue of not
> > tying up the CPU so much:
> ...
> > QueryPerformanceCounter(&clicks);
> ...
> Unfortunately, a high-performance counter may not be available, in
> which case clicks will be 0. In that case, the return-value of
> rand_byte will also be 0. By the way, the function is not available in
> Win32s.

So much the worse for Win32s. As I recall, Win32s is still close
enough to DOS that you can just peek into some memory location
for the system clock. Maybe this is what GetTickCount() does.

> I suspect the granularity of GetTickCount (miliseconds) is way too
> coarse to be used instead of QueryPerformanceCounter, in particular
> because this is also the granularity of Sleep. But if not, perhaps one

Although on my NT box Sleep() never comes back in less than 15
milliseconds.

> could use GetTickCount instead if QueryPerformanceCounter fails?
> My documentation states the following about GetTickCount:
> >If the function succeeds, the return value is the number of
> milliseconds that have elapsed since Windows was started
> Unfortunately, it neglects to mention what happens if it does not
> succeed... I can not quite imagine why it would not succeed, but it is
> very frustrating not to know for sure.

Such frustration is the typical state of a Win32 programmer.
Too bad we can't just check the source code.
 
> It could perhaps look like this (I have only modified one line):
> unsigned char rand_byte(int nbits)
> {
> unsigned int result=0;
> int i;
> LARGE_INTEGER clicks;
> for (i=0; i<nbits; ++i) {
> Sleep(1);
> if(QueryPerformanceCounter(&clicks)==0)
> clicks.LowPart=GetTickCount();
> // rotate low byte left 1 bit and XOR in LSB of counter
> result = (((result << 1) | (result >> 7)) & 0xFF) ^
> (clicks.LowPart);
> }
> return result;
> }
>
> Alternatively, one could perhaps use a different algorithm if
> QueryPerformanceCounter fails.

Perhaps, but we are getting into pretty machine/OS specific
programming here. Even the "portable" versions based on clock()
can easily fail to produce random numbers. So the thing to do
is just test.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk