Ticket #1272 (closed merge: fixed)

Opened 6 years ago

Last modified 5 years ago

newStdGen returns the same value on successive calls

Reported by: guest Owned by: igloo
Priority: normal Milestone: 6.8.1
Component: libraries/base Version: 6.6
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Difficulty: Unknown
Test Case: Blocked By:
Blocking: Related Tickets:

Description (last modified by igloo) (diff)

It seems newStdGen only depends on the second, it should have better resolution and/or use /dev/random.

Test program:

   import Random
   main = newStdGen >>= print

compiled with ghc 6.6 or 6.7 (at some point in time) Running "date; ./random" gives:

Thu Apr 12 10:51:54 CEST 2007
1938403181 6764
Thu Apr 12 10:51:54 CEST 2007
1938403181 6764
Thu Apr 12 10:51:55 CEST 2007
529729936 6762
Thu Apr 12 10:51:55 CEST 2007
529729936 6762
Thu Apr 12 10:51:56 CEST 2007
1023702766 6762
Thu Apr 12 10:51:56 CEST 2007
1023702766 6762
Thu Apr 12 10:52:03 CEST 2007
186545450 6762
Thu Apr 12 10:52:04 CEST 2007
680518280 6762
Thu Apr 12 10:52:04 CEST 2007
680518280 6762

Change History

Changed 6 years ago by guest

mkStdRNG :: Integer -> IO StdGen
mkStdRNG o = do
    ct          <- getCPUTime
    (TOD sec _) <- getClockTime
    return (createStdGen (sec * 12345 + ct + o))

The problem here is that getCPUTime often returns zero. Possibly because this happens at the start of the program, and with too low resolution. Experimenting a bit, it appears that the smallest non-zero value for getCPUTime is 4*109, i.e. a resolution of 4ms?

Changed 6 years ago by guest

Some more comments/experiments on this.

(I'd submit a patch, but I don't understand the rationale behind the current implementation.)

* Successive invocations of getClockTime always gives me different results - even if the fraction is in even millions (i.e. µs). So using the fraction would work on GHC at least. Presumably there is a reason this isn't done already?

* Initializing on modern Unixes (at least Linux and Solaris) should probably be from reading from /dev/urandom (/dev/random may block waiting for entropy - if an application depends on true randomness that critically, I think it should handle it manually.) The current Read instance fails if it is fed strings longer than six characters, and the resulting StdGens? from when it works appear limited in range. This is probably not critical(?)

Changed 6 years ago by igloo

  • component changed from Compiler to libraries/base
  • description modified (diff)
  • milestone set to 6.8

I see no reason not to use the second component of TOD; it doesn't need a type conversion or anything, and even if it is very low precision it won't hurt to include it.

We have a small collection of Random bugs accumulating! Hopefully someone will be able to give the library the once-over for 6.8.

Changed 6 years ago by simonmar

  • owner set to simonmar

Changed 6 years ago by simonmar

  • owner changed from simonmar to igloo
  • type changed from bug to merge

Fixed

Fri Oct 26 08:40:58 PDT 2007  Simon Marlow <simonmar@microsoft.com>
  * FIX #1272: include the picoseconds field of ClockTime in the seed

Changed 6 years ago by igloo

  • status changed from new to closed
  • resolution set to fixed

Merged

Changed 6 years ago by igloo

  • milestone changed from 6.8 branch to 6.8.1

Changed 5 years ago by simonmar

  • architecture changed from Unknown to Unknown/Multiple

Changed 5 years ago by simonmar

  • os changed from Unknown to Unknown/Multiple
Note: See TracTickets for help on using tickets.