The testing procedure I've used is described in an earlier post. There is one extension, compared to the earlier post: every rotation and reversal is also complemented for a total of 256 subtests. I'll call the extended version "RRC-64-40-TF2-0.94" for "Reversed, rotated, complemented-64 bits, 2^40 bytes, PractRand 0.94 with -tf 2". Without further ado, here's "Moremur", a statistically stronger but equally fast mixer:
uint64_t moremur(uint64_t x) {
x ^= x >> 27;
x *= 0x3C79AC492BA7B653UL;
x ^= x >> 33;
x *= 0x1C69B3F74AC4AE35UL;
x ^= x >> 27;
return x;
}
One strong flaw with this construction, i.e. the first operation being an xor-shift, is that there are many increments that will lead to few or none of the less significant bits being one.
This in turn implies that the less significant bits will be zero after the first two operations, xor-shift and multiply.
Particularly bad increments have this form: γ=(2s+1)a,a<2s, s being the first shift and a being sparse.
x ^= x >> 27;
x *= 0x3C79AC492BA7B653UL;
x ^= x >> 33;
x *= 0x1C69B3F74AC4AE35UL;
x ^= x >> 27;
return x;
}
In the table below, Moremur outperforms Murmur3 and Variant13 by quite some margin.
γ | Murmur3 | Variant13 | Moremur |
---|---|---|---|
0x0000000000000001 |
217 | 219 | 233 |
0x0000000000000003 |
217 | 217 | 234 |
0x0000000000000005 |
217 | 218 | 234 |
0x0000000000000009 |
216 | 218 | 234 |
0x0000010000000001 |
218 | 221 | 241 |
0xffffffffffffffff |
217 | 219 | 233 |
0x0000000000ffffff |
217 | 223 | 237 |
0xffffff0000000001 |
218 | 223 | 243 |
0x0000000000555555 |
218 | 228 | 242 |
0x1111111111110001 |
225 | 230 | >246 |
0x7777777777770001 |
228 | 234 | >245 |
0x7f7f7f7f33333333 |
230 | 233 | >246 |
0x5555550000000001 |
221 | 227 | 245 |
0xc45a11730cc8ffe3 |
239 | >242 | 2? |
0x2b13b77d0b289bbd |
239 | >242 | 2? |
0x40ead42ca1cd0131 |
240 | >242 | 2? |
ror64(reverse(x, R) ^ |
|||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
FORWARD | REVERSED | ||||||||||||||||||||||||||||||||
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 | 33 | 19 | 19 | 19 | 22 | 22 | 24 | 25 | 28 | 27 | 28 | 29 | 16 | 16 | 16 | 17 | 16 | 17 | 19 | 19 | 20 | 28 | 27 | 28 | 34 | 29 | 29 | 35 | 36 | 37 | 37 | 38 | |
16 | 17 | 17 | 18 | 19 | 19 | 19 | 19 | 20 | 21 | 22 | 23 | 23 | 24 | 25 | 26 | 27 | 36 | 35 | 35 | 39 | 40 | 34 | 31 | 31 | 39 | 40 | 39 | 38 | 37 | 34 | 34 | 36 | |
32 | 28 | 29 | 30 | 31 | 31 | 32 | 33 | 33 | 34 | 34 | 34 | 34 | 34 | 33 | 32 | 32 | 28 | 34 | 33 | 32 | 32 | 31 | 33 | 33 | 34 | 34 | 34 | 35 | 35 | 36 | 37 | 36 | |
48 | 32 | 28 | 28 | 28 | 29 | 29 | 29 | 29 | 30 | 30 | 30 | 30 | 31 | 31 | 31 | 32 | 31 | 31 | 31 | 33 | 36 | 37 | 36 | 28 | 33 | 34 | 31 | 31 | 28 | 25 | 22 | 19 | |
ror64(reverse(x, R) ^ |
|||||||||||||||||||||||||||||||||
FORWARD | REVERSED | ||||||||||||||||||||||||||||||||
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 | 33 | 19 | 19 | 19 | 22 | 22 | 24 | 25 | 28 | 29 | 18 | 28 | 15 | 16 | 16 | 17 | 16 | 17 | 19 | 21 | 21 | 26 | 28 | 30 | 34 | 31 | 34 | 34 | 36 | 36 | 37 | 37 | |
16 | 17 | 18 | 18 | 19 | 19 | 19 | 19 | 19 | 21 | 22 | 23 | 24 | 24 | 25 | 26 | 27 | 36 | 35 | 35 | 39 | 40 | 34 | 31 | 31 | 39 | 40 | 39 | 38 | 37 | 34 | 34 | 36 | |
32 | 28 | 29 | 30 | 30 | 32 | 33 | 33 | 34 | 34 | 35 | 35 | 34 | 34 | 32 | 33 | 32 | 28 | 34 | 33 | 32 | 32 | 31 | 33 | 33 | 34 | 34 | 34 | 35 | 36 | 36 | 36 | 36 | |
48 | 32 | 28 | 28 | 28 | 28 | 28 | 29 | 29 | 29 | 30 | 30 | 30 | 31 | 31 | 32 | 32 | 31 | 31 | 31 | 33 | 35 | 35 | 34 | 28 | 32 | 32 | 31 | 30 | 28 | 25 | 22 | 19 |
ror64(reverse(x, R) ^ |
|||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
FORWARD | REVERSED | ||||||||||||||||||||||||||||||||
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 | 17 | 18 | 18 | 18 | 17 | 16 | 16 | 16 | 16 | 15 | 15 | 17 | 15 | 14 | 15 | 15 | 15 | 17 | 18 | 18 | 18 | 17 | 17 | 16 | 16 | 14 | 14 | 14 | 14 | 14 | 14 | 17 | |
16 | 14 | 14 | 14 | 14 | 14 | 15 | 15 | 15 | 15 | 15 | 16 | 16 | 16 | 16 | 15 | 15 | 17 | 17 | 16 | 17 | 17 | 17 | 17 | 18 | 19 | 17 | 18 | 18 | 17 | 16 | 14 | 14 | |
32 | 16 | 16 | 17 | 17 | 16 | 16 | 14 | 14 | 16 | 15 | 14 | 15 | 15 | 15 | 15 | 15 | 15 | 16 | 17 | 18 | 18 | 17 | 17 | 17 | 17 | 16 | 14 | 14 | 14 | 14 | 15 | 15 | |
48 | 15 | 14 | 14 | 14 | 14 | 14 | 15 | 15 | 15 | 15 | 15 | 16 | 17 | 17 | 17 | 17 | 17 | 17 | 17 | 17 | 17 | 17 | 17 | 18 | 18 | 19 | 19 | 18 | 18 | 18 | 17 | 16 | |
ror64(reverse(x, R) ^ |
|||||||||||||||||||||||||||||||||
FORWARD | REVERSED | ||||||||||||||||||||||||||||||||
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 | 17 | 17 | 18 | 17 | 17 | 15 | 16 | 16 | 16 | 15 | 15 | 17 | 14 | 15 | 15 | 15 | 14 | 17 | 18 | 18 | 17 | 17 | 16 | 17 | 16 | 15 | 14 | 14 | 14 | 14 | 16 | 17 | |
16 | 14 | 14 | 14 | 14 | 15 | 15 | 15 | 15 | 15 | 15 | 16 | 16 | 16 | 16 | 15 | 15 | 17 | 17 | 16 | 17 | 17 | 17 | 17 | 18 | 18 | 18 | 17 | 16 | 15 | 15 | 14 | 14 | |
32 | 16 | 17 | 17 | 17 | 16 | 14 | 14 | 14 | 15 | 15 | 14 | 15 | 14 | 15 | 15 | 14 | 15 | 15 | 17 | 18 | 18 | 17 | 17 | 17 | 17 | 16 | 15 | 14 | 14 | 14 | 14 | 15 | |
48 | 14 | 14 | 14 | 14 | 14 | 14 | 15 | 15 | 15 | 15 | 15 | 16 | 17 | 17 | 17 | 17 | 17 | 17 | 17 | 16 | 17 | 17 | 17 | 17 | 18 | 19 | 19 | 18 | 18 | 18 | 17 | 15 |
ror64(reverse(x, R) ^ |
|||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
FORWARD | REVERSED | ||||||||||||||||||||||||||||||||
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 | 19 | 17 | 18 | 18 | 18 | 17 | 18 | 18 | 18 | 18 | 18 | 19 | 19 | 16 | 17 | 17 | 16 | 17 | 18 | 18 | 18 | 19 | 19 | 20 | 20 | 19 | 20 | 20 | 19 | 20 | 20 | 19 | |
16 | 17 | 17 | 16 | 17 | 16 | 16 | 17 | 17 | 16 | 17 | 16 | 17 | 17 | 17 | 18 | 18 | 20 | 19 | 21 | 18 | 19 | 21 | 19 | 22 | 20 | 21 | 22 | 21 | 20 | 22 | 22 | 19 | |
32 | 19 | 19 | 19 | 19 | 19 | 19 | 19 | 19 | 19 | 19 | 20 | 20 | 19 | 20 | 19 | 19 | 18 | 18 | 18 | 19 | 19 | 20 | 20 | 19 | 20 | 20 | 19 | 20 | 20 | 20 | 20 | 19 | |
48 | 17 | 17 | 16 | 17 | 17 | 17 | 16 | 17 | 16 | 17 | 17 | 17 | 18 | 18 | 19 | 19 | 21 | 18 | 18 | 21 | 19 | 22 | 20 | 21 | 19 | 18 | 18 | 18 | 18 | 18 | 18 | 18 | |
ror64(reverse(x, R) ^ |
|||||||||||||||||||||||||||||||||
FORWARD | REVERSED | ||||||||||||||||||||||||||||||||
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 | 19 | 17 | 18 | 18 | 18 | 17 | 18 | 18 | 18 | 18 | 18 | 18 | 19 | 16 | 17 | 17 | 16 | 17 | 18 | 18 | 18 | 19 | 19 | 20 | 20 | 19 | 20 | 20 | 19 | 20 | 20 | 19 | |
16 | 17 | 17 | 16 | 17 | 16 | 17 | 17 | 17 | 16 | 17 | 16 | 17 | 17 | 17 | 17 | 18 | 20 | 19 | 21 | 18 | 18 | 21 | 19 | 22 | 20 | 21 | 22 | 21 | 20 | 22 | 22 | 19 | |
32 | 19 | 19 | 19 | 19 | 19 | 19 | 19 | 19 | 19 | 19 | 20 | 20 | 19 | 20 | 20 | 19 | 18 | 18 | 18 | 19 | 19 | 20 | 20 | 19 | 20 | 20 | 19 | 20 | 20 | 19 | 20 | 19 | |
48 | 16 | 17 | 16 | 16 | 17 | 17 | 16 | 17 | 16 | 17 | 17 | 17 | 18 | 18 | 19 | 19 | 21 | 19 | 19 | 21 | 19 | 22 | 20 | 21 | 19 | 18 | 18 | 18 | 18 | 18 | 18 | 18 |