Conversation
Use a SplitMix64 generator instead of the OS-seeded RNG for the rho start and offset values. The generator is created for each target and seeded from it, so factoring a number does the same work on every call, whatever the thread factored before.
Merging this PR will improve performance by ×4.5
|
| Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|
| ⚡ | three 39-bit primes (u128) |
480.2 ms | 107.7 ms | ×4.5 |
Tip
Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.
Comparing sylvestre:rho-deterministic-seed (7becc10) with main (866bc2c)
Footnotes
-
9 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #121 +/- ##
==========================================
+ Coverage 78.64% 86.12% +7.48%
==========================================
Files 13 17 +4
Lines 2585 3972 +1387
Branches 230 265 +35
==========================================
+ Hits 2033 3421 +1388
+ Misses 552 548 -4
- Partials 0 3 +3
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Rename RhoSeed to SplitMix64 and give it its own module, with references to the algorithm (Steele, Lea and Flood, OOPSLA 2014) and to Vigna's reference implementation. Check it against the reference outputs.
|
We should run tests for a big-endian target in CI: cargo +nightly miri test --target s390x-unknown-linux-gnu |
| pub(crate) struct SplitMix64(u64); | ||
|
|
||
| impl SplitMix64 { | ||
| pub(crate) fn new(seed: u64) -> Self { |
There was a problem hiding this comment.
xoshiro crate handles endianness explicitly:
impl SplitMix64 {
/// Seed a `SplitMix64` from a `u64`.
pub fn from_seed_u64(seed: u64) -> SplitMix64 {
let mut x = [0; 8];
LittleEndian::write_u64(&mut x, seed);
SplitMix64::from_seed(x)
}
}|
Tests pass under Miri for a big-endian architecture: $cargo +nightly miri test --tests splitmix64 --target s390x-unknown-linux-gnu
running 2 tests
test splitmix64::tests::reference_values ... ok
test splitmix64::tests::reproducible ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 136 filtered out; finished in 0.31s |
Use a SplitMix64 generator instead of the OS-seeded RNG for the rho start and offset values. The generator is created for each target and seeded from it, so factoring a number does the same work on every call, whatever the thread factored before.