This repository includes multiple implementations of the Mandelbrot algorithm in Rust, showing how parallelism and SIMD can be used to speed it up.
From fastest to slowest:
std::simd
: Uses the built-in portable SIMD support in Rust, requires unstable compiler.pulp
SIMD: Use thepulp
crate to implement portable SIMD operations.pulp
can use the stable compiler.wide
SIMD: Use thewide
crate to implement portable SIMD operations.wide
can use the stable compiler.- Scalar with autovectorization: A scalar version written so the compiler can autovectorize it, i.e. decide to use SIMD automatically.
- Scalar: The standard algorithm, one value at a time.
All implementations use parallelism out of the box, using Rayon.
Much of this is based on the mandelbrot
benchmark from the benchmarksgame, as implemented in the since-superseded packed_simd
project.
Changes from the original implementation:
- Updated to use the newer Rust portable SIMD API (nightly only at the moment).
- Simplified the calculation logic so it's easier to understand.
- Autovectorized implementation contributed by giovannicuccu.
pulp
implementation contributed by sarah quiñones.
Licensed under MIT or Apache 2.0, at your choice, copyrighted by the Rust Project Developers, with minor changes by Itamar Turner-Trauring.
http://mathworld.wolfram.com/MandelbrotSet.html
It takes four arguments in this order:
width
: width of the image to renderheight
: height of the image to renderalgorithm
: algorithm to use:scalar
: scalar algorithmsimd
: parallelized SIMD algorithmispc
: ISPC + tasks algorithm
--color
(optional): enables colorized output, which also determines the image format.- disabled (default): PBM: Portable BitMap format (black & white output)
- enabled: PPM: Portable PixMap format (colored output)
The resulting image is piped to stdout
.
cargo run --release -- 400 400 --algo simd > output.ppm
outputs:
cargo run --release -- 400 400 --algo simd --color > output.ppm
outputs:
Make sure you have hyperfine
installed.
Multi-threaded:
$ ./benchmark.sh
Single-threaded:
$ RAYON_NUM_THREADS=1 ./benchmark.sh