Skip to content

Commit bb1262f

Browse files
authored
Use Xoshiro256PlusPlus in examples/rayon-monte-carlo.rs (#1805)
2 parents 521fab6 + 39fcc34 commit bb1262f

2 files changed

Lines changed: 28 additions & 34 deletions

File tree

benches/benches/generators.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use core::time::Duration;
1212
use criterion::measurement::WallTime;
1313
use criterion::{BenchmarkGroup, Criterion, black_box, criterion_group, criterion_main};
1414
use rand::prelude::*;
15-
use rand::rngs::SysRng;
15+
use rand::rngs::{SysRng, Xoshiro128PlusPlus, Xoshiro256PlusPlus};
1616
use rand_pcg::{Pcg32, Pcg64, Pcg64Dxsm, Pcg64Mcg};
1717

1818
criterion_group!(
@@ -45,8 +45,8 @@ pub fn random_bytes(c: &mut Criterion) {
4545
bench(&mut g, "chacha8", rand::make_rng::<ChaCha8Rng>());
4646
bench(&mut g, "chacha12", rand::make_rng::<ChaCha12Rng>());
4747
bench(&mut g, "chacha20", rand::make_rng::<ChaCha20Rng>());
48-
bench(&mut g, "std", rand::make_rng::<StdRng>());
49-
bench(&mut g, "small", rand::make_rng::<SmallRng>());
48+
bench(&mut g, "xoshiro128++", rand::make_rng::<Xoshiro128PlusPlus>());
49+
bench(&mut g, "xoshiro256++", rand::make_rng::<Xoshiro256PlusPlus>());
5050
bench(&mut g, "os", UnwrapErr(SysRng));
5151
bench(&mut g, "thread", rand::rng());
5252

@@ -73,8 +73,8 @@ pub fn random_u32(c: &mut Criterion) {
7373
bench(&mut g, "chacha8", rand::make_rng::<ChaCha8Rng>());
7474
bench(&mut g, "chacha12", rand::make_rng::<ChaCha12Rng>());
7575
bench(&mut g, "chacha20", rand::make_rng::<ChaCha20Rng>());
76-
bench(&mut g, "std", rand::make_rng::<StdRng>());
77-
bench(&mut g, "small", rand::make_rng::<SmallRng>());
76+
bench(&mut g, "xoshiro128++", rand::make_rng::<Xoshiro128PlusPlus>());
77+
bench(&mut g, "xoshiro256++", rand::make_rng::<Xoshiro256PlusPlus>());
7878
bench(&mut g, "os", UnwrapErr(SysRng));
7979
bench(&mut g, "thread", rand::rng());
8080

@@ -101,8 +101,8 @@ pub fn random_u64(c: &mut Criterion) {
101101
bench(&mut g, "chacha8", rand::make_rng::<ChaCha8Rng>());
102102
bench(&mut g, "chacha12", rand::make_rng::<ChaCha12Rng>());
103103
bench(&mut g, "chacha20", rand::make_rng::<ChaCha20Rng>());
104-
bench(&mut g, "std", rand::make_rng::<StdRng>());
105-
bench(&mut g, "small", rand::make_rng::<SmallRng>());
104+
bench(&mut g, "xoshiro128++", rand::make_rng::<Xoshiro128PlusPlus>());
105+
bench(&mut g, "xoshiro256++", rand::make_rng::<Xoshiro256PlusPlus>());
106106
bench(&mut g, "os", UnwrapErr(SysRng));
107107
bench(&mut g, "thread", rand::rng());
108108

@@ -128,8 +128,8 @@ pub fn init_gen(c: &mut Criterion) {
128128
bench::<ChaCha8Rng>(&mut g, "chacha8");
129129
bench::<ChaCha12Rng>(&mut g, "chacha12");
130130
bench::<ChaCha20Rng>(&mut g, "chacha20");
131-
bench::<StdRng>(&mut g, "std");
132-
bench::<SmallRng>(&mut g, "small");
131+
bench::<Xoshiro128PlusPlus>(&mut g, "xoshiro128++");
132+
bench::<Xoshiro256PlusPlus>(&mut g, "xoshiro256++");
133133

134134
g.finish()
135135
}
@@ -154,8 +154,8 @@ pub fn init_from_u64(c: &mut Criterion) {
154154
bench::<ChaCha8Rng>(&mut g, "chacha8");
155155
bench::<ChaCha12Rng>(&mut g, "chacha12");
156156
bench::<ChaCha20Rng>(&mut g, "chacha20");
157-
bench::<StdRng>(&mut g, "std");
158-
bench::<SmallRng>(&mut g, "small");
157+
bench::<Xoshiro128PlusPlus>(&mut g, "xoshiro128++");
158+
bench::<Xoshiro256PlusPlus>(&mut g, "xoshiro256++");
159159

160160
g.finish()
161161
}
@@ -183,8 +183,8 @@ pub fn init_from_seed(c: &mut Criterion) {
183183
bench::<ChaCha8Rng>(&mut g, "chacha8");
184184
bench::<ChaCha12Rng>(&mut g, "chacha12");
185185
bench::<ChaCha20Rng>(&mut g, "chacha20");
186-
bench::<StdRng>(&mut g, "std");
187-
bench::<SmallRng>(&mut g, "small");
186+
bench::<Xoshiro128PlusPlus>(&mut g, "xoshiro128++");
187+
bench::<Xoshiro256PlusPlus>(&mut g, "xoshiro256++");
188188

189189
g.finish()
190190
}

examples/rayon-monte-carlo.rs

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,40 +24,34 @@
2424
//! the square at random, calculate the fraction that fall within the circle,
2525
//! and multiply this fraction by 4.
2626
//!
27-
//! Note on determinism:
28-
//! It's slightly tricky to build a parallel simulation using Rayon
29-
//! which is both efficient *and* reproducible.
27+
//! ### A note on the use of explicit batching
3028
//!
31-
//! Rayon's ParallelIterator api does not guarantee that the work will be
32-
//! batched into identical batches on every run, so we can't simply use
33-
//! map_init to construct one RNG per Rayon batch.
29+
//! Rayon's `ParallelIterator::map_init` does not guarantee that the work will
30+
//! be batched identically on every run. By using the `map` function to
31+
//! construct fixed-size batches, each with a dedicated PRNG, we are able to
32+
//! achieve a deterministic result with little extra code.
3433
//!
35-
//! Instead, we do our own batching, so that a Rayon work item becomes a
36-
//! batch. Then we can fix our rng stream to the batched work item.
37-
//! Batching amortizes the cost of constructing the Rng from a fixed seed
38-
//! over BATCH_SIZE trials. Manually batching also turns out to be faster
39-
//! for the nondeterministic version of this program as well.
34+
//! Due to the small work-item size (the inner loop) batching also improves
35+
//! performance significantly due to the reduced scheduling overhead.
4036
41-
use chacha20::ChaCha8Rng;
4237
use rand::distr::{Distribution, Uniform};
38+
use rand::rngs::Xoshiro256PlusPlus;
4339
use rand_core::SeedableRng;
4440
use rayon::prelude::*;
4541

46-
static SEED: u64 = 0;
47-
static BATCH_SIZE: u64 = 10_000;
48-
static BATCHES: u64 = 1000;
42+
const BATCH_SIZE: u64 = 10_000;
43+
const BATCHES: u64 = 1000;
4944

5045
fn main() {
5146
let range = Uniform::new(-1.0f64, 1.0).unwrap();
5247

5348
let in_circle = (0..BATCHES)
5449
.into_par_iter()
5550
.map(|i| {
56-
let mut rng = ChaCha8Rng::seed_from_u64(SEED);
57-
// We chose ChaCha because it's fast, has suitable statistical properties for simulation,
58-
// and because it supports this set_stream() api, which lets us choose a different stream
59-
// per work item. ChaCha supports 2^64 independent streams.
60-
rng.set_stream(i);
51+
// If we didn't care for determinism we could use SmallRng instead:
52+
// let mut rng: SmallRng = rand::make_rng();
53+
let mut rng = Xoshiro256PlusPlus::seed_from_u64(i);
54+
6155
let mut count = 0;
6256
for _ in 0..BATCH_SIZE {
6357
let a = range.sample(&mut rng);
@@ -71,7 +65,7 @@ fn main() {
7165
.sum::<usize>();
7266

7367
// assert this is deterministic
74-
assert_eq!(in_circle, 7852263);
68+
assert_eq!(in_circle, 7853568);
7569

7670
// prints something close to 3.14159...
7771
println!(

0 commit comments

Comments
 (0)