I am playing around with RNG’s, specifically this one:
function squares(ctr::UInt64, key::UInt64)::UInt32
y = x = ctr * key; z = y + key
x = x*x + y; x = (x>>32) | (x<<32) # round 1
x = x*x + z; x = (x>>32) | (x<<32) # round 2
x = x*x + y; x = (x>>32) | (x<<32) # round 3
return (x*x + z) >> 32 # round 4
end
I know about julialang generic tips for performance but I wonder if there are specific tips for RNG’s typical operations.
I imagine there must be some because I did a quick benchmark comparing squares
with Julia rand
and, despite rand
being more complex (Mersenne Twister I believe), it is still considerably faster than squares
. See below.
using BenchmarkTools
key = 0xc8e4fd154ce32f6d
ctr = UInt64.(1:10^6);
@benchmark squares.(ctr, key)
BechmarkTools.Trial: 2069 samples with 1 evaluations.
Range (min … max): 2.139 ms … 4.657 ms ┊ GC (min … max): 0.00% … 10.45%
Time (median): 2.327 ms ┊ GC (median): 0.00%
Time (mean ± σ): 2.398 ms ± 259.592 μs ┊ GC (mean ± σ): 1.76% ± 4.84%
█ ▂ ▁▁
█▄▄█▆██████▇▆▆▅▅▄▄▃▃▃▃▃▃▃▃▃▃▃▄▃▃▃▃▃▃▃▂▂▃▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▁▂▁▂ ▃
2.14 ms Histogram: frequency by time 3.33 ms <
Memory estimate: 3.81 MiB, allocs estimate: 4.
@benchmark rand(10^6)
BechmarkTools.Trial: 2766 samples with 1 evaluations.
Range (min … max): 1.212 ms … 4.856 ms ┊ GC (min … max): 0.00% … 0.00%
Time (median): 1.305 ms ┊ GC (median): 0.00%
Time (mean ± σ): 1.791 ms ± 869.906 μs ┊ GC (mean ± σ): 7.98% ± 13.41%
█▇▆▄▃▂▁▁▁ ▂▃▃▁ ▁▂▂▁ ▁▂▂▂▁ ▁
██████████▇▇▃▃▄▃▃▃▃▃▃▁▃▃█████▆▆▆▆▅▃▄▁▁█████▇▅▆▄▆▄█████▆█▇▆▅ █
1.21 ms Histogram: log(frequency) by time 470 ms <
Memory estimate: 7.63 MiB, allocs estimate: 2.