Uniform sampling: use Canon's method - #1287
Conversation
Based on canon-uniform-benches branch, revised
Also: add "unbiased" feature flag
This is a small tweak unsupported by evidence, but brings SIMD in line with unbiased integer range sampling.
Allows simpler tests
Note: unbiased does pass current value-stability tests, but could fail extra ones in the future.
Baseline results (new benchmark on master)
New results (compared to baseline)
New results (unbiased feature)
...I hate micro-benchmarking (see results in #1286). Looks like we should just use Lemire's method for distribution sampling in all cases. |
Agreed, especially if it is less biased. |
|
Bench re-runs (lower clock speed, better formatted): results.ods Highlights:
So, yes, this supports the idea that we should always use Lemire's method for distribution sampling. |
|
Remaining question: whether to keep both biased and unbiased options for single-sampling (using a feature flag). See #494. I am inclined to keep this under the following conditions:
There is not a strong rationale for this however, we could reduce to just one implementation (either). |
|
I'm inclined to merge this as-is. Review please, maybe @TheIronBorn or @vks? |
|
Thanks @TheIronBorn. Updated. |
|
I'd like to merge this but am still waiting for a reviewer to approve (policy requires review is not by the author). @TheIronBorn you last reviewed this; would you mind revisiting? |
Also: * Add uniform distribution benchmarks * Add "unbiased" feature flag * Fix feature simd_support * Uniform: impl PartialEq, Eq where possible * CI: benches now require small_rng; build-test unbiased
|
If I understand, you kept using Canon for simple sampling, but added roughly Lemire for Also what you call Lemire differs somewhat from Algorithm 5 in his paper: https://arxiv.org/pdf/1805.10941 It appears you simply restarts his algorithm 5 whenever he'd do the modulo operations. Afaik what you do makes sense and avoids ever doing modulo, but maybe his full algorithm runs faster for some ranges? |
@burdges this work isn't fresh in my mind, but from what I remember the choices were largely benchmark-led (though I won't claim that those benchmarks were comprehensive or representative of many platforms; most benches were run on AMD Zen 3 Vermeer). |
|
I figured it out partially.. You have the OpenBSD algorithm 3 from Lemire's paper, which gives the same output as Lemire. It's slightly faster than Lemire when doing repeated runs on the same range, and slightly slower when the range changes, like in a shuffle. I'm not sure if Canon has different output from Lemire. If so, that's potentially confusing. |
Closes #570, #1145, #1154, #1196, #1286. See also #1172 (TODO: SIMD), #494 (here we add "unbiased" feature flag).
Also implements
PartialEqfor all ourUniformimpls andEqfor all but FP. See #1217.Yet another PR to finally update
Uniforminteger sampling (maybe):