Skip to content

Instantly share code, notes, and snippets.

@pixelmager
Created March 26, 2020 13:31
Show Gist options
  • Save pixelmager/f374861211582704989f95ecc169a4ed to your computer and use it in GitHub Desktop.
Save pixelmager/f374861211582704989f95ecc169a4ed to your computer and use it in GitHub Desktop.
glsl hash testing

just gathering the comments from https://www.shadertoy.com/view/WttXWX in a place I can actually find, which also has more markdown :)

OK, results are in: as 32 bit RNGs, the 3-round Wellons function here is marked as weak in just 2 tests, with no failures. The 2-round Wellons function has 4 weaks and 1 failure, the murmurhash derivative only slightly worse with 5 weaks and 1 failure. Jenkins and Wang have many failures (Wang fails almost everything) so aren't really in the running.

http://webhome.phy.duke.edu/~rgb/General/dieharder.php http://simul.iro.umontreal.ca/testu01/guideshorttestu01.pdf p 88-157 https://github.com/umontreal-simul/latticetester

Individual tests (just the negative results from the 50 or so tests):

// --- choose one:
//#define hashi(x)   lowbias32(x)
  #define hashi(x)   triple32(x) 

  #define hash(x)  ( float( hashi(x) ) / float( 0xffffffffU ) )

//bias: 0.17353355999581582 ( very probably the best of its kind )
uint lowbias32(uint x)
{
    x ^= x >> 16;
    x *= 0x7feb352dU;
    x ^= x >> 15;
    x *= 0x846ca68bU;
    x ^= x >> 16;
    return x;
}

// bias: 0.020888578919738908 = minimal theoretic limit
uint triple32(uint x)
{
    x ^= x >> 17;
    x *= 0xed5ad4bbU;
    x ^= x >> 11;
    x *= 0xac4c1b51U;
    x ^= x >> 15;
    x *= 0x31848babU;
    x ^= x >> 14;
    return x;
}

wellons2 (lowbias32)

TEST RESULT
diehard_opso 0 2097152 100 0.00000001 FAILED
sts_serial 15 100000 100 0.99636479 WEAK
rgb_minimum_distance 4 10000 1000 0.99754988 WEAK
rgb_permutations 3 100000 100 0.99946899 WEAK
rgb_lagged_sum 5 1000000 100 0.99575897 WEAK

wellons3 (triple32)

TEST RESULT
diehard_parking_lot 0 12000 100 0.99650356 WEAK
rgb_minimum_distance 5 10000 1000 0.00125775 WEAK

murmur

TEST RESULT
diehard_craps 0 200000 100 0.00012089 WEAK
marsaglia_tsang_gcd 0 10000000 100 0.00000000 FAILED
sts_serial 6 100000 100 0.99932034 WEAK
rgb_bitdist 5 100000 100 0.99933401 WEAK
rgb_permutations 5 100000 100 0.99646826 WEAK
rgb_lagged_sum 18 1000000 100 0.99788947 WEAK

glsl-sine hash

Using the sine hash from https://www.shadertoy.com/view/ltyBWm (which visually looks fine) and using to generate 16-bit random numbers, C++ code:

float sinhash(uint x, uint y) {
  float seed = 71.33*x+852.381*y;
  return fmod(fabs(38351.43*sin(14.13*seed)),1.0);
}

uint sinhash(uint n) {
  float x = sinhash(n >> 16, n & 0xffff);
  return uint(x*0x10000);
}

Result is not awful, but not great:
TEST RESULT
diehard_operm5 0 1000000 100 0.00000000 FAILED
diehard_squeeze 0 100000 100 0.00000000 FAILED
diehard_runs 0 100000 100 0.99996083 WEAK
marsaglia_tsang_gcd 0 10000000 100 0.00000000 FAILED
marsaglia_tsang_gcd 0 10000000 100 0.00000000 FAILED
sts_runs 2 100000 100 0.00000004 FAILED
sts_serial 3 100000 100 0.00021384 WEAK
sts_serial 13 100000 100 0.00145147 WEAK
rgb_bitdist 4 100000 100 0.00050052 WEAK
rgb_bitdist 8 100000 100 0.00000000 FAILED
rgb_lagged_sum 0 1000000 100 0.00000000 FAILED
rgb_lagged_sum 1 1000000 100 0.00000000 FAILED
rgb_lagged_sum 2 1000000 100 0.00000000 FAILED
rgb_lagged_sum 3 1000000 100 0.00000000 FAILED
rgb_lagged_sum 4 1000000 100 0.00000000 FAILED
rgb_lagged_sum 5 1000000 100 0.00000000 FAILED
rgb_lagged_sum 6 1000000 100 0.00000000 FAILED
<more failures>

Very similar results from the "official" sine hash:

float hash(vec2 p)
{
    return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);
}
TEST RESULT
diehard_operm5 0 1000000 100 0.00000000 FAILED
diehard_dna 0 2097152 100 0.00144687 WEAK
diehard_squeeze 0 100000 100 0.00000012 FAILED
diehard_runs 0 100000 100 0.00000000 FAILED
diehard_runs 0 100000 100 0.00000029 FAILED
diehard_craps 0 200000 100 0.00000003 FAILED
sts_serial 1 100000 100 0.00273519 WEAK
sts_serial 9 100000 100 0.99532417 WEAK
sts_serial 10 100000 100 0.99710812 WEAK
rgb_permutations 3 100000 100 0.00008555 WEAK
rgb_permutations 4 100000 100 0.00175526 WEAK
rgb_lagged_sum 0 1000000 100 0.00000000 FAILED
rgb_lagged_sum 1 1000000 100 0.00000008 FAILED
rgb_lagged_sum 2 1000000 100 0.00000000 FAILED
rgb_lagged_sum 3 1000000 100 0.00000000 FAILED
rgb_lagged_sum 4 1000000 100 0.00000000 FAILED
rgb_lagged_sum 5 1000000 100 0.00000000 FAILED
<more failures>

LCG

OK, some more results for a 32-bit linear congruential generator, this one is from Numerical Recipes:

uint lcg(uint) {
  static uint value = 1;
  value *= 1664525U;
  value += 1013904223U;
  return value;
}
TEST RESULT
diehard_rank_6x8 0 100000 100 0.00000000 FAILED
diehard_bitstream 0 2097152 100 0.00000000 FAILED
diehard_opso 0 2097152 100 0.00000000 FAILED
diehard_oqso 0 2097152 100 0.00000000 FAILED
diehard_dna 0 2097152 100 0.00000000 FAILED
diehard_count_1s_str 0 256000 100 0.00000000 FAILED
diehard_count_1s_byt 0 256000 100 0.00000000 FAILED
diehard_parking_lot 0 12000 100 0.99983528 WEAK
marsaglia_tsang_gcd 0 10000000 100 0.00000000 FAILED
marsaglia_tsang_gcd 0 10000000 100 0.00000000 FAILED
sts_serial 2 100000 100 0.00001211 WEAK
sts_serial 3 100000 100 0.00000001 FAILED
sts_serial 3 100000 100 0.00001378 WEAK
sts_serial 4 100000 100 0.00000000 FAILED
sts_serial 4 100000 100 0.00000492 WEAK
sts_serial 5 100000 100 0.00000000 FAILED
<more sts_serial failures>
rgb_bitdist 1 100000 100 0.00000000 FAILED
rgb_bitdist 2 100000 100 0.00000000 FAILED
<more rgb_bitdist failures>
rgb_minimum_distance 2 10000 1000 0.00000000 FAILED
rgb_minimum_distance 3 10000 1000 0.00292069 WEAK
rgb_minimum_distance 4 10000 1000 0.00000000 FAILED
rgb_minimum_distance 5 10000 1000 0.00000004 FAILED
rgb_lagged_sum 11 1000000 100 0.99708426 WEAK
rgb_lagged_sum 13 1000000 100 0.99998108 WEAK
rgb_lagged_sum 22 1000000 100 0.99964562 WEAK
dab_bytedistrib 0 51200000 1 1.00000000 FAILED
dab_dct 256 50000 1 0.00000000 FAILED
dab_filltree2 0 5000000 1 0.00000000 FAILED
dab_filltree2 1 5000000 1 0.00000000 FAILED
dab_monobit2 12 65000000 1 1.00000000 FAILED
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment