Skip to content

Latest commit

 

History

History

3_10_threads

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

Step 3.10: Multithreading and parallelism

Estimated time: 1 day

One of main Rust's design goals is a concurrency. Rust has a strong opinion about that, while allows different concurrent models to coexist.

Threads

Rust has built-in support for native threads in form of the std::thread module of its standard library.

Traditionally, threads are used for solving CPU-bound problems, as they allow to execute tasks in parallel. However, in practice, threads are often used to solve I/O-bound problems too, especially when asynchronous I/O is not supported well (which is true for Rust std library at the moment).

crossbeam crate also provides implementation of scoped threads, which allow to borrow values from a stack. They are also available in form of std::thread::scope, as of Rust 1.63.

For better understanding Rust threads design, concepts, usage, and features (especially TLS is important and widely used one), read through the following articles:

Synchronization

The threads synchronization is a wide topic, but generally it's done via atomic operations, shared state with an exclusive access, or by threads communication. Rust has built-in support for all of them.

Atomic operations are represented by std::sync::atomic module of Rust standard library (and, additionally, atomic crate).

Exclusive access may be controlled via primitives of std::sync module of Rust standard library.

Threads communication is commonly represented via channels and is implemented in std::sync::mpsc module of Rust standard library.

Despite that, there is also the crossbeam crate, providing more feature-rich and optimized concurrency and synchronization primitives. The most notable is crossbeam-channel as an enhancement of std channel implementations.

For better understanding and familiarity with Rust synchronization primitives design, concepts, usage, and features, read through the following articles:

Parallelism

The important concept to understand is how concurrency and parallelism differ.

Rust ecosystem has support for parallelism in form of rayon and dpc-pariter crates, which make it easy to convert a sequential iterator to execute in parallel threads.

Another way to perform parallel data processing without using threads is SIMD instructions usage. If an algorithm is parallelizable enough, applying SIMD instructions may increase performance drastically. Rust ecosystem provides basic support for SIMD instructions in a form of packed_simd crate.

For better understanding and familiarity with parallelism in Rust, read through the following articles:

Task

Write a program with the following workflow:

  • Producer is a separate thread, which continuously generates square matrixes of random u8 elements and size 4096.
  • Consumer is a separate thread, which takes a generated matrix, counts sum of all its elements and prints the sum to STDOUT.
  • There are only 1 Producer and 2 Consumers.
  • Counting sum of matrix elements should be parallelized.

Questions

After completing everything above, you should be able to answer (and understand why) the following questions:

  • What is concurrency? What is parallelism? How do they relate to each other and how do they differ?
  • How parallelism is represented in Rust? Which are common crates for using it?
  • What are the main ways of threads synchronization in Rust? Which advantages and disadvantages does each one have? What are the use-cases for each one?