diff options
author | Yves Orton <demerphq@gmail.com> | 2022-08-05 13:18:02 +0200 |
---|---|---|
committer | Yves Orton <demerphq@gmail.com> | 2022-08-12 22:29:05 +0200 |
commit | bf2a3dae9f4f828fd1f2f8aaf4769f96520c9552 (patch) | |
tree | b58ad50f0d8d828bb5a890686e0ce7e82ae529ae /handy.h | |
parent | 08da5deb5d0c842dab3fe5f4f5a450972a0eb67c (diff) | |
download | perl-bf2a3dae9f4f828fd1f2f8aaf4769f96520c9552.tar.gz |
Add a new env var PERL_RAND_SEED
This env var can be used to trigger a repeatable run of a script which
calls C<srand()> with no arguments, either explicitly or implicitly
via use of C<rand()> prior to calling srand(). This is implemented in
such a way that calling C<srand()> with no arguments in forks or
subthreads (again explicitly or implicitly) will receive their own seed
but the seeds they receive will be repeatable.
This is intended for debugging and perl development performance testing,
and for running the test suite consistently. It is documented that the
exact seeds used to initialize the random state are unspecified, and
that they may change between releases or even builds. The only guarantee
provided is that the same perl executable will produce the same results
twice all other things being equal. In practice and in core testing we
do expect consistency, but adding the tightest set of restrictions on
our commitments seemed sensible.
The env var is ignored when perl is run setuid or setgid similarly to
the C<PERL_INTERNAL_RAND_SEED> env var.
Diffstat (limited to 'handy.h')
-rw-r--r-- | handy.h | 72 |
1 files changed, 63 insertions, 9 deletions
@@ -2967,21 +2967,75 @@ last-inclusive range. * are very useful when you want an integer to "dance" in a random way, * but you also never want it to become 0 and thus false. * - * Obviously they leave x unchanged if it starts out as 0. */ + * Obviously they leave x unchanged if it starts out as 0. + * + * We have two variants just because that can be helpful in certain + * places. There is no advantage to either, they are equally bad as each + * other as far RNG's go. Sufficiently random for many purposes, but + * insufficiently random for serious use as they fail important tests in + * the Test01 BigCrush RNG test suite by L’Ecuyer and Simard. (Note + * that Drand48 also fails BigCrush). The main point is they produce + * different sequences and in places where we want some randomlike + * behavior they are cheap and easy. + * + * Marsaglia was one of the early researchers into RNG testing and wrote + * the Diehard RNG test suite, which after his death become the + * Dieharder RNG suite, and was generally supplanted by the Test01 suite + * by L'Ecruyer and associates. + * + * There are dozens of shift parameters that create a pseudo random ring + * of integers 1..2^N-1, if you need a different sequence just read the + * paper and select a set of parameters. In fact, simply reversing the + * shift order from L/R/L to R/L/R should result in another valid + * example, but read the paper before you do that. + * + * PDF of the original paper: + * https://www.jstatsoft.org/article/download/v008i14/916 + * Wikipedia: + * https://en.wikipedia.org/wiki/Xorshift + * Criticism: + * https://www.iro.umontreal.ca/~lecuyer/myftp/papers/xorshift.pdf + * Test01: + * http://simul.iro.umontreal.ca/testu01/tu01.html + * Diehard: + * https://en.wikipedia.org/wiki/Diehard_tests + * Dieharder: + * https://webhome.phy.duke.edu/~rgb/General/rand_rate/rand_rate.abs + * + */ -#define PERL_XORSHIFT64(x) \ +/* 32 bit version */ +#define PERL_XORSHIFT32_A(x) \ STMT_START { \ - (x) ^= (x) << 13; \ - (x) ^= (x) >> 17; \ - (x) ^= (x) << 5; \ + (x) ^= ((x) << 13); \ + (x) ^= ((x) >> 17); \ + (x) ^= ((x) << 5); \ +} STMT_END + +/* 64 bit version */ +#define PERL_XORSHIFT64_A(x) \ +STMT_START { \ + (x) ^= ((x) << 13); \ + (x) ^= ((x) >> 7); \ + (x) ^= ((x) << 17); \ } STMT_END /* 32 bit version */ -#define PERL_XORSHIFT32(x) \ +#define PERL_XORSHIFT32_B(x) \ +STMT_START { \ + (x) ^= ((x) << 5); \ + (x) ^= ((x) >> 27); \ + (x) ^= ((x) << 8); \ +} STMT_END + +/* 64 bit version - currently this is unused, + * it is provided here to complement the 32 bit _B + * variant which IS used. */ +#define PERL_XORSHIFT64_B(x) \ STMT_START { \ - (x) ^= (x) << 13; \ - (x) ^= (x) >> 7; \ - (x) ^= (x) << 17; \ + (x) ^= ((x) << 15); \ + (x) ^= ((x) >> 49); \ + (x) ^= ((x) << 26); \ } STMT_END |