1
1
# Parallel Compilation
2
2
3
- Most of the compiler is not parallel. This represents an opportunity for
4
- improving compiler performance.
3
+ As of <!-- date: 2021-09 --> September 2021, The only stage of the compiler
4
+ that is already parallel is codegen. The nightly compiler implements query evaluation,
5
+ but there is a lot of correctness work that needs to be done. The lack of parallelism at other stages
6
+ also represents an opportunity for improving compiler performance. One can try out the current
7
+ parallel compiler work by enabling it in the ` config.toml ` .
5
8
6
- As of <!-- date: 2021-07 --> July 2021, work on explicitly parallelizing the
7
- compiler has stalled. There is a lot of design and correctness work that needs
8
- to be done.
9
+ These next few sections describe where and how parallelism is currently used,
10
+ and the current status of making parallel compilation the default in ` rustc ` .
11
+
12
+ The underlying thread-safe data-structures used in the parallel compiler
13
+ can be found in ` rustc_data_structures/sync.rs ` . Some of these data structures
14
+ use the ` parking_lot ` API.
15
+
16
+ ## Code Gen
17
+
18
+ During [ monomorphization] [ monomorphization ] the compiler splits up all the code to
19
+ be generated into smaller chunks called _ codegen units_ . These are then generated by
20
+ independent instances of LLVM running in parallel. At the end, the linker
21
+ is run to combine all the codegen units together into one binary.
22
+
23
+ ## Query System
9
24
10
- One can try out the current parallel compiler work by enabling it in the
11
- ` config.toml ` .
25
+ The query model has some properties that make it actually feasible to evaluate
26
+ multiple queries in parallel without too much of an effort:
12
27
13
- There are a few basic ideas in this effort:
28
+ - All data a query provider can access is accessed via the query context, so
29
+ the query context can take care of synchronizing access.
30
+ - Query results are required to be immutable so they can safely be used by
31
+ different threads concurrently.
14
32
15
- - There are a lot of loops in the compiler that just iterate over all items in
16
- a crate. These can possibly be parallelized.
17
- - We can use (a custom fork of) [ ` rayon ` ] to run tasks in parallel. The custom
18
- fork allows the execution of DAGs of tasks, not just trees.
19
- - There are currently a lot of global data structures that need to be made
20
- thread-safe. A key strategy here has been converting interior-mutable
21
- data-structures (e.g. ` Cell ` ) into their thread-safe siblings (e.g. ` Mutex ` ).
33
+
34
+ When a query ` foo ` is evaluated, the cache table for ` foo ` is locked.
35
+
36
+ - If there already is a result, we can clone it, release the lock and
37
+ we are done.
38
+ - If there is no cache entry and no other active query invocation computing the
39
+ same result, we mark the key as being "in progress", release the lock and
40
+ start evaluating.
41
+ - If there * is* another query invocation for the same key in progress, we
42
+ release the lock, and just block the thread until the other invocation has
43
+ computed the result we are waiting for. This cannot deadlock because, as
44
+ mentioned before, query invocations form a DAG. Some thread will always make
45
+ progress.
46
+
47
+ ## Current Status
48
+
49
+ As of <!-- date: 2021-07 --> July 2021, work on explicitly parallelizing the
50
+ compiler has stalled. There is a lot of design and correctness work that needs
51
+ to be done.
22
52
23
53
[ `rayon` ] : https://crates.io/crates/rayon
24
54
@@ -45,3 +75,4 @@ are a bit out of date):
45
75
[ imlist ] : https://github.com/nikomatsakis/rustc-parallelization/blob/master/interior-mutability-list.md
46
76
[ irlo1 ] : https://internals.rust-lang.org/t/help-test-parallel-rustc/11503
47
77
[ tracking ] : https://github.com/rust-lang/rust/issues/48685
78
+ [ monomorphization ] :https://rustc-dev-guide.rust-lang.org/backend/monomorph.html
0 commit comments