måndag 8 november 2021

Applying the RRC-64-test to the degski64 and Lea64 mixers

In LXM: better splittable pseudorandom number generators (and almost as fast) by Guy L Steele and Sebastiano Vigna, approaches for pseudo-random number generation through mixing PRNGs with different structure by way of a non-linear mixer are discussed. The three 64-bit mixers considered in the paper are Austin Appleby's Murmur3 (and Stafford's Variant 13 of Murmur3), of which I've written about here and here, degski64 and Lea64, described in the LXM paper.

degski64 and Lea64 are similar to Murmur3 in structure but use xor-shifts by 32 bits exclusively (Murmur3 included for reference):

uint64_t murmur64(uint64_t z) {
  z ^= (z >> 33);
  z *= 0xff51afd7ed558ccdull;
  z ^= (z >> 33);
  z *= 0xc4ceb9fe1a85ec53ull;
  return z ^ (z >> 33);
}

uint64_t lea64(uint64_t z) {
  z ^= (z >> 32);
  z *= 0xdaba0b6eb09322e3ull;
  z ^= (z >> 32);
  z *= 0xdaba0b6eb09322e3ull;
  return z ^ (z >> 32);
}

uint64_t degski64(uint64_t z) {
  z ^= (z >> 32);
  z *= 0xd6e8feb86659fd93ull;
  z ^= (z >> 32);
  z *= 0xd6e8feb86659fd93ull;
  return z ^ (z >> 32);
}
I am not aware of the design rationale for the 32 bit shifts; one would think that they would be faster on some platforms. A short test with clang-12 on a Ryzen 5900X gives timings for the 4 functions that are within 0.5% of each other, my guess is that they are equally fast (sampled 200 Gops/each mixer, ~2.57 Gops/s).

Applying RRC-64 to degski64 and Lea64

Sadly, neither mixer is particularly strong but fails RRC-64 about as badly as the original Murmur3/Variant13. Moremur is, at least as far as RRC-64 goes, a much stronger mixer with the same number of operations.

As can be seen from the tables below, the constants used in degski64 and Lea64 are no stronger (w.r.t. RRC-64) than Murmur3/Variant 13 but much weaker than Moremur.

degski64 failures, $2^{40}$ bytes maximum.
ror64(reverse(x, R) ^ 0x0000000000000000, r)
FORWARDREVERSED
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 17171517151516151517161515141515 14141415141716151716171515171615
16 14151515151515151515151515151516 17151615161615171515151517151716
32 16161517151516151517161614141415 14141415141716151716151515171615
48 14151515151515151515151515151517 17151615171615171515151517161717
ror64(reverse(x, R) ^ 0xFFFFFFFFFFFFFFFF, r)
FORWARDREVERSED
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 17171517151516161516161514141415 14141615141715151716151515171615
16 14151515151514151515151515151616 17151615171615171515151517151716
32 15161517151516151516151614141515 14141415141715151716151515171615
48 14151515151515151415151515151617 17151615171615171515151517151717
Lea64 failures, $2^{40}$ bytes maximum.
ror64(reverse(x, R) ^ 0x0000000000000000, r)
FORWARDREVERSED
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 17171517151516151517161515141515 14141415141716151716171515171615
16 14151515151515151515151515151516 17151615161615171515151517151716
32 16161517151516151517161614141415 14141415141716151716151515171615
48 14151515151515151515151515151517 17151615171615171515151517161717
ror64(reverse(x, R) ^ 0xFFFFFFFFFFFFFFFF, r)
FORWARDREVERSED
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 17171517151516161516161514141415 14141615141715151716151515171615
16 14151515151514151515151515151616 17151615171615171515151517151716
32 15161517151516151516151614141515 14141415141715151716151515171615
48 14151515151515151415151515151617 17151615171615171515151517151717
Moremur failures, $2^{40}$ bytes maximum.
ror64(reverse(x, R) ^ 0x0000000000000000, r)
FORWARDREVERSED
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 3319191922222425282728291616161716171919202827283429293536373738
16 1717181919191920212223232425262736353539403431313940393837343436
32 2829303131323333343434343433323228343332323133333434343535363736
48 3228282829292929303030303131313231313133363736283334313128252219
ror64(reverse(x, R) ^ 0xFFFFFFFFFFFFFFFF, r)
FORWARDREVERSED
Offset 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 3319191922222425282918281516161716171921212628303431343436363737
16 1718181919191919212223242425262736353539403431313940393837343436
32 2829303032333334343535343432333228343332323133333434343536363636
48 3228282828282929293030303131323231313133353534283232313028252219

Conclusion

It would be interesting to see to what extent a (much) stronger mixer would affect the results in the LXM paper. I believe that Moremur is a stronger drop-in replacement for Murmur3, Variant13, degski64 and Lea64 with comparable, if not identical, speed.

3 kommentarer:

  1. Tjena Pelle! I'm but an amateur in the PRNG field but I just wanted to say that I really enjoy your posts and findings!

    SvaraRadera
    Svar
    1. Thanks for your kind words. From the greeting, Swedish I presume?

      Radera
    2. Correct! I guessed you were somewhere from scandinavia and threw that in there, haha.

      Radera

Applying the RRC-64-test to the degski64 and Lea64 mixers

In LXM: better splittable pseudorandom number generators (and almost as fast) by Guy L Steele and Sebastiano Vigna, approaches for pseud...