Ben Chuanlong Du's Blog

And let it direct your passion with reason.

Parallel RNGs With Rayon in Rust

The Rust Rand Book - Parallel RNGs has a very good summary about parallel RNGs. It also gives code examples using the rayon library. However, a few things to notice.

  1. rand::ThreadRng (obtained by calling rand::thread_rng) is often used in code examples of parallel RNGs as it uses thread-local storage and is seeded automatically (lazily and uniquely) on each thread.

    use rand::Rng;
    use rayon::prelude::*;
    let a: Vec<_> = (1i32..1_000_000)
            || rand::thread_rng(),  // get the thread-local RNG
            |rng, x| if rng.gen() { // randomly negate items
            } else {

    While rand::ThreadRng is convenient to use as parallel RNGs, it is based on StdRng (currently, ChaCha block cipher with 12 rounds) which might be too slow for statistical simulations. If that's the case, you can use a faster RNG (e.g., SmallRng) with thread-local storage as parallel RNGs. Please refer to Customized RNGs with Thread-local Storage for details.

  2. rayon::iter::ParallelIterator::map_init allows you do some initializing work before running each job. Note that the init closure passed to map_init is called once per rayon job NOT per rayon worker thead. A rayon worker thread typically executes many jobs. If you need to ensure some intializing work per rayon worker thread (e.g., if you want to use the same RNG for jobs executed by the same worker thread), you have to leverage thread-local storage in the init closure. For more discussions, please refer to Thread-Local Storage for Rayon .

  3. rayon::iter::ParallelIterator::with_min_len can be used to set the minimum number of items processed per job. When necessary, its parameter can be tuned to improve performance.

Customized RNGs with Thread-local Storage

Please refer to Thread-Local Storage for Rayon for detailed discussions.