Tuning murmur3

Jon Maiga, 2020-08-11

Since I already had the tools available and matters relatively fresh in my head, I decided to see how far I can get the xmxmx construction:

uint64_t xmxmx(uint64_t x) {
	x ^= x >> xc1;
	x *= mc;
	x ^= x >> xc2;
	x *= mc;
	x ^= x >> xc3;    	
	return x;
}

Again I am only using the mixer as a counter based PRNG (xmxmx(counter++)) and seeing how far it takes us in PractRand.

MurMur3 and SplitMix both use the xmxmx construction and will fail really early, around 2202^{20} bytes (as counter based).

I started with the xor-constants I found in tuning bit mixers and did some further tweaking using the same methodology. Once the xor-constants had been settled I additionally ran SFFS (see same article) to find a decent multiplier constant.

Here is the result

uint64_t xmxmx(uint64_t x) {
	x ^= x >> 27;
	x *= 0xe9846af9b1a615dull;
	x ^= x >> 25;
	x *= 0xe9846af9b1a615dull;
	x ^= x >> 27;    	
	return x;
}

which fails PractRand at 2412^{41} bytes.

By adding a multiplication before the first xor-shift we can get really good quality by at least passing PractRand 2452^{45} bytes as I did in the mx3 pseudo random number generator.