Changeset 90fb672


Ignore:
Timestamp:
Mar 21, 2023, 7:44:45 AM (18 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, ast-experimental, master
Children:
1205b3e
Parents:
12b006c
Message:

use splitmix32/64 to prime set seed for all PRNG

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/bits/random.hfa

    r12b006c r90fb672  
    1010// Created On       : Fri Jan 14 07:18:11 2022
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Mar 20 10:01:40 2023
    13 // Update Count     : 180
     12// Last Modified On : Mon Mar 20 21:45:24 2023
     13// Update Count     : 186
    1414//
    1515
     
    131131#ifdef __cforall                                                                                // don't include in C code (invoke.h)
    132132
    133 // Splitmix64
    134133// https://rosettacode.org/wiki/Pseudo-random_numbers/Splitmix64
    135 // Splitmix64 is not recommended for demanding random number requirements,
    136 // but is often used to calculate initial states for other more complex
    137 // pseudo-random number generators.                             
     134//
     135// Splitmix64 is not recommended for demanding random number requirements, but is often used to calculate initial states
     136// for other more complex pseudo-random number generators (see https://prng.di.unimi.it).
     137// Also https://rosettacode.org/wiki/Pseudo-random_numbers/Splitmix64.
    138138static inline uint64_t splitmix64( uint64_t & state ) {
    139139    state += 0x9e3779b97f4a7c15;
     
    149149} // splitmix64_set_seed
    150150
    151 // Splitmix32
    152151// https://github.com/bryc/code/blob/master/jshash/PRNGs.md#splitmix32
    153 // Splitmix32 is not recommended for demanding random number requirements,
    154 // but is often used to calculate initial states for other more complex
    155 // pseudo-random number generators.
    156 // SplitMix32 is a 32 bit variant of Splitmix64
     152//
     153// Splitmix32 is not recommended for demanding random number requirements, but is often used to calculate initial states
     154// for other more complex pseudo-random number generators (see https://prng.di.unimi.it).
     155
    157156static inline uint32_t splitmix32( uint32_t & state ) {
    158157    state += 0x9e3779b9;
     
    169168
    170169#ifdef __SIZEOF_INT128__
    171         //--------------------------------------------------
    172         static inline uint64_t lehmer64( __uint128_t & state ) {
    173                 __uint128_t ret = state;
    174                 state *= 0x_da94_2042_e4dd_58b5;
    175                 return ret >> 64;
    176         } // lehmer64
    177 
    178         static inline void lehmer64_set_seed( __uint128_t & state, uint64_t seed ) {
    179                 // The seed needs to be coprime with the 2^64 modulus to get the largest period, so no factors of 2 in the seed.
    180                 state = seed;
    181                 lehmer64( state );                                                              // prime
    182         } // lehmer64_set_seed
    183 
    184         //--------------------------------------------------
    185         static inline uint64_t wyhash64( uint64_t & state ) {
    186                 uint64_t ret = state;
    187                 state += 0x_60be_e2be_e120_fc15;
    188                 __uint128_t tmp;
    189                 tmp = (__uint128_t) ret * 0x_a3b1_9535_4a39_b70d;
    190                 uint64_t m1 = (tmp >> 64) ^ tmp;
    191                 tmp = (__uint128_t)m1 * 0x_1b03_7387_12fa_d5c9;
    192                 uint64_t m2 = (tmp >> 64) ^ tmp;
    193                 return m2;
    194         } // wyhash64
     170//--------------------------------------------------
     171static inline uint64_t lehmer64( __uint128_t & state ) {
     172        __uint128_t ret = state;
     173        state *= 0x_da94_2042_e4dd_58b5;
     174        return ret >> 64;
     175} // lehmer64
     176
     177static inline void lehmer64_set_seed( __uint128_t & state, uint64_t seed ) {
     178        // The seed needs to be coprime with the 2^64 modulus to get the largest period, so no factors of 2 in the seed.
     179        state = splitmix64( seed );                                                     // prime
     180} // lehmer64_set_seed
     181
     182//--------------------------------------------------
     183static inline uint64_t wyhash64( uint64_t & state ) {
     184        uint64_t ret = state;
     185        state += 0x_60be_e2be_e120_fc15;
     186        __uint128_t tmp;
     187        tmp = (__uint128_t) ret * 0x_a3b1_9535_4a39_b70d;
     188        uint64_t m1 = (tmp >> 64) ^ tmp;
     189        tmp = (__uint128_t)m1 * 0x_1b03_7387_12fa_d5c9;
     190        uint64_t m2 = (tmp >> 64) ^ tmp;
     191        return m2;
     192} // wyhash64
     193
     194static inline void wyhash64_set_seed( uint64_t & state, uint64_t seed ) {
     195        state = splitmix64( seed );                                                     // prime
     196} // wyhash64_set_seed
    195197#endif // __SIZEOF_INT128__
    196198
     
    227229
    228230static inline void xoshiro256pp_set_seed( xoshiro256pp_t & state, uint64_t seed ) {
    229     // these are done explicitly in this order to attain repeatable seeding.
    230     // do not call splitmix64 directly in the state init since order of argument evaluation
    231     // may not be consistent leading to irreproducible seeding
    232     uint64_t seed1 = splitmix64( seed );
     231    // To attain repeatable seeding, compute seeds separately because the order of argument evaluation is undefined.
     232    uint64_t seed1 = splitmix64( seed );                                // prime
    233233    uint64_t seed2 = splitmix64( seed );
    234234    uint64_t seed3 = splitmix64( seed );
    235235    uint64_t seed4 = splitmix64( seed );
    236236        state = (xoshiro256pp_t){ seed1, seed2, seed3, seed4 };
    237         xoshiro256pp( state );                                                          // prime
    238237} // xoshiro256pp_set_seed
    239238
     
    269268
    270269static inline void xoshiro128pp_set_seed( xoshiro128pp_t & state, uint32_t seed ) {
    271     // these are done explicitly in this order to attain repeatable seeding.
    272     // do not call splitmix32 directly in the state init since order of argument evaluation
    273     // may not be consistent leading to irreproducible seeding
    274     uint32_t seed1 = splitmix32( seed );
     270    // To attain repeatable seeding, compute seeds separately because the order of argument evaluation is undefined.
     271    uint32_t seed1 = splitmix32( seed );                                // prime
    275272    uint32_t seed2 = splitmix32( seed );
    276273    uint32_t seed3 = splitmix32( seed );
    277274    uint32_t seed4 = splitmix32( seed );
    278275        state = (xoshiro128pp_t){ seed1, seed2, seed3, seed4 };
    279         xoshiro128pp( state );                                                          // prime
    280276} // xoshiro128pp_set_seed
    281277
     
    290286
    291287static inline void xorshift_13_7_17_set_seed( uint64_t & state, uint64_t seed ) {
    292         state = seed;
    293         xorshift_13_7_17( state );                                                      // prime
     288        state = splitmix64( seed );                                                     // prime
    294289} // xorshift_13_7_17_set_seed
    295290
     
    308303
    309304static inline void xorshift_6_21_7_set_seed( uint32_t & state, uint32_t seed ) {
    310         state = seed;
    311         xorshift_6_21_7( state );                                                       // prime
     305    state = splitmix32( seed );                                                 // prime
    312306} // xorshift_6_21_7_set_seed
    313307
     
    323317
    324318static inline void xorshift_12_25_27_set_seed( uint64_t & state, uint64_t seed ) {
    325         state = seed;
    326         xorshift_12_25_27( state );                                                     // prime
     319        state = splitmix64( seed );                                                     // prime
    327320} // xorshift_12_25_27_set_seed
    328321
     
    345338
    346339static inline void kiss_64_set_seed( kiss_64_t & rs, uint64_t seed ) with(rs) {
    347         z = 1; w = 1; jsr = 4; jcong = seed;
    348         kiss_64( rs );                                                                          // prime
     340        z = 1; w = 1; jsr = 4; jcong = splitmix64( seed );      // prime
    349341} // kiss_64_set_seed
    350342
     
    374366
    375367static inline void xorwow_set_seed( xorwow_t & rs, uint32_t seed ) {
    376     // these are done explicitly in this order to attain repeatable seeding.
    377     // do not call splitmix32 directly in the state init since order of argument evaluation
    378     // may not be consistent leading to irreproducible seeding
    379     uint32_t seed1 = splitmix32( seed );
     368    // To attain repeatable seeding, compute seeds separately because the order of argument evaluation is undefined.
     369    uint32_t seed1 = splitmix32( seed );                                // prime
    380370    uint32_t seed2 = splitmix32( seed );
    381371    uint32_t seed3 = splitmix32( seed );
    382372    uint32_t seed4 = splitmix32( seed );
    383373        rs = (xorwow_t){ seed1, seed2, seed3, seed4, 0 };
    384         xorwow( rs );                                                                           // prime
    385374} // xorwow_set_seed
    386375
     
    388377// Used in __tls_rand_fwd
    389378#define M  (1_l64u << 48_l64u)
    390 #define A  (25214903917_l64u)
    391 #define AI (18446708753438544741_l64u)
     379#define A  (25_214_903_917_l64u)
     380#define AI (18_446_708_753_438_544_741_l64u)
    392381#define C  (11_l64u)
    393382#define D  (16_l64u)
  • tests/.expect/PRNG.x64.txt

    r12b006c r90fb672  
    11
    22                    PRNG()     PRNG(5)   PRNG(0,5)
    3        2629641414891406278           3           0
    4       11972157801652581900           3           5
    5        9470682093934978437           2           2
    6         316134424938305673           2           2
    7        5572275127081588144           0           3
    8       12394954141290188855           2           2
    9       15386440704589550620           2           1
    10        5760167266331356361           2           5
    11        8021670258373873290           2           5
    12        8813161879342109574           1           4
    13       10525294799876107814           2           0
    14       14801827301969351008           3           0
    15       17016612914230924215           0           0
    16        5485205801221744751           3           2
    17        6143666691223938511           4           0
    18       15086131934315954459           4           5
    19        4547668615176940328           4           5
    20       17718351571399359777           0           5
    21        2636252641646208341           4           0
    22       12820158953704882599           0           4
     3      13944458589275087071           3           2
     4        129977468648444256           0           4
     5       2357727400298891021           2           2
     6       8855179187835660146           3           3
     7       9957620185645882382           4           1
     8      13396406983727409795           0           5
     9       3342782395220265920           0           5
     10       1707651271867677937           1           0
     11      16402561450140881681           0           1
     12      17838519215740313729           4           2
     13       7425936020594490136           4           0
     14       4174865704721714670           3           5
     15      16055269689200152092           0           2
     16      15091270195803594018           1           5
     17      11807315541476180798           1           1
     18      10697186588988060306           4           1
     19      14665526411527044929           3           2
     20      11289342279096164771           2           5
     21      16126980828050300615           1           4
     22       7821578301767524260           4           1
    2323seed 1009
    2424
     
    3333
    3434                    prng()     prng(5)   prng(0,5)
    35        2629641414891406278           3           0
    36       11972157801652581900           3           5
    37        9470682093934978437           2           2
    38         316134424938305673           2           2
    39        5572275127081588144           0           3
    40       12394954141290188855           2           2
    41       15386440704589550620           2           1
    42        5760167266331356361           2           5
    43        8021670258373873290           2           5
    44        8813161879342109574           1           4
    45       10525294799876107814           2           0
    46       14801827301969351008           3           0
    47       17016612914230924215           0           0
    48        5485205801221744751           3           2
    49        6143666691223938511           4           0
    50       15086131934315954459           4           5
    51        4547668615176940328           4           5
    52       17718351571399359777           0           5
    53        2636252641646208341           4           0
    54       12820158953704882599           0           4
     35      13944458589275087071           3           2
     36        129977468648444256           0           4
     37       2357727400298891021           2           2
     38       8855179187835660146           3           3
     39       9957620185645882382           4           1
     40      13396406983727409795           0           5
     41       3342782395220265920           0           5
     42       1707651271867677937           1           0
     43      16402561450140881681           0           1
     44      17838519215740313729           4           2
     45       7425936020594490136           4           0
     46       4174865704721714670           3           5
     47      16055269689200152092           0           2
     48      15091270195803594018           1           5
     49      11807315541476180798           1           1
     50      10697186588988060306           4           1
     51      14665526411527044929           3           2
     52      11289342279096164771           2           5
     53      16126980828050300615           1           4
     54       7821578301767524260           4           1
    5555seed 1009
    5656
     
    6565
    6666                   prng(t)   prng(t,5) prng(t,0,5)
    67        2629641414891406278           3           0
    68       11972157801652581900           3           5
    69        9470682093934978437           2           2
    70         316134424938305673           2           2
    71        5572275127081588144           0           3
    72       12394954141290188855           2           2
    73       15386440704589550620           2           1
    74        5760167266331356361           2           5
    75        8021670258373873290           2           5
    76        8813161879342109574           1           4
    77       10525294799876107814           2           0
    78       14801827301969351008           3           0
    79       17016612914230924215           0           0
    80        5485205801221744751           3           2
    81        6143666691223938511           4           0
    82       15086131934315954459           4           5
    83        4547668615176940328           4           5
    84       17718351571399359777           0           5
    85        2636252641646208341           4           0
    86       12820158953704882599           0           4
     67      13944458589275087071           3           2
     68        129977468648444256           0           4
     69       2357727400298891021           2           2
     70       8855179187835660146           3           3
     71       9957620185645882382           4           1
     72      13396406983727409795           0           5
     73       3342782395220265920           0           5
     74       1707651271867677937           1           0
     75      16402561450140881681           0           1
     76      17838519215740313729           4           2
     77       7425936020594490136           4           0
     78       4174865704721714670           3           5
     79      16055269689200152092           0           2
     80      15091270195803594018           1           5
     81      11807315541476180798           1           1
     82      10697186588988060306           4           1
     83      14665526411527044929           3           2
     84      11289342279096164771           2           5
     85      16126980828050300615           1           4
     86       7821578301767524260           4           1
    8787seed 1009
    8888
  • tests/concurrent/pthread/.expect/bounded_buffer.x64.txt

    r12b006c r90fb672  
    1 producer total value is 38160
    2 consumer total value is 38160
     1producer total value is 39780
     2consumer total value is 39780
Note: See TracChangeset for help on using the changeset viewer.