|
2 | 2 |
|
3 | 3 | This program plots the Mandelbrot set and writes it out as a PNG file. It uses Rust's concurrency primitives to distribute the work across eight threads.
|
4 | 4 |
|
5 |
| -Different commits show different implementation strategies: |
| 5 | +The book shows several different versions of this program: single- and multi-threaded versions in the "Tour of Rust" chapter, and a final version based on the Rayon crate in the "Concurrency" chapter, which makes more effective use of parallelism. |
| 6 | + |
| 7 | +Each of these versions appears on a different branch in this repository: |
6 | 8 |
|
7 | 9 | * [Branch `single-threaded`](https://github.com/ProgrammingRust/mandelbrot/tree/single-threaded)
|
8 | 10 | is the base version of the program. It does all the work on the main
|
9 |
| - thread. |
| 11 | + thread. This is the first version shown in the "Tour of Rust" chapter. |
10 | 12 |
|
11 | 13 | * [Branch `bands`](https://github.com/ProgrammingRust/mandelbrot/tree/bands)
|
12 |
| - splits the plotting area up into eight bands, and assigns one thread |
13 |
| - to each. This often makes poor use of the threads, because some |
14 |
| - bands take significantly longer than others to complete: once a fast |
15 |
| - thread completes its band, its CPU goes idle while its less |
16 |
| - fortunate brethren are still hard at work. |
| 14 | + splits the plotting area up into eight bands, and assigns one thread to |
| 15 | + each. This often makes poor use of the threads, because some bands take |
| 16 | + significantly longer than others to complete: once a fast thread completes |
| 17 | + its band, its CPU goes idle while its less fortunate brethren are still hard |
| 18 | + at work. This is the final version shown in the Tour. |
17 | 19 |
|
18 | 20 | * [Branch `task-queue`](https://github.com/ProgrammingRust/mandelbrot/tree/task-queue)
|
19 | 21 | gets an almost perfect linear speedup from its threads. It splits
|
20 | 22 | the plotting area up into many more bands, and then has threads draw
|
21 | 23 | bands from a common pool until the pool is empty. When a thread
|
22 | 24 | finishes one band, it goes back for more work. Since the bands still
|
23 | 25 | take different amounts of time to render, the problem cited above
|
24 |
| - still occurs, but on a much smaller scale. |
| 26 | + still occurs, but on a much smaller scale. This version is not shown in the book. |
25 | 27 |
|
26 | 28 | * [Branch `lockfree`](https://github.com/ProgrammingRust/mandelbrot/tree/lockfree)
|
27 | 29 | uses Rust's atomic types to implement a lock-free iterator type, and
|
28 | 30 | uses that to dole out bands from the pool instead of a
|
29 | 31 | mutex-protected count. On Linux, this is no faster than the
|
30 | 32 | mutex-based version, which isn't too surprising: on Linux, locking
|
31 | 33 | and unlocking an uncontended mutex *is* simply a pair of atomic
|
32 |
| - operations. |
| 34 | + operations. This version is also not shown in the book. |
33 | 35 |
|
34 | 36 | * [Branch `rayon`](https://github.com/ProgrammingRust/mandelbrot/tree/rayon)
|
35 |
| - uses the Rayon library instead of Crossbeam. Rayon provides a |
36 |
| - *parallel iterator* API that makes our code much simpler. It looks |
37 |
| - a lot like Rust code that uses plain old iterators. |
| 37 | + uses the Rayon library instead of Crossbeam. Rayon provides a *parallel |
| 38 | + iterator* API that makes our code much simpler. It looks a lot like Rust |
| 39 | + code that uses plain old iterators. This is the final version shown in the |
| 40 | + Concurrency chapter. |
38 | 41 |
|
39 | 42 | ## License
|
40 | 43 |
|
|
0 commit comments