Skip to content

Parallelize rustc via multi-process approach #47518

Closed
@michaelwoerister

Description

@michaelwoerister

For big crates, the Rust compiler can be stuck in single-threaded execution for quite some time because only the last phase of compilation is properly parallelized. This issue describes one particular approach for making most of compilation parallel.

Basic Concept: Spawn multiple rustc processes that compile "vertical slices" of a crate

The compiler's internal architecture has become rather flexible and demand-driven over the last couple of years and one could imagine implementing an option for the compiler that allows it to just compile part of a crate. Given a deterministic partitioning for a crate, one could then run multiple compilation processes for compiling disjunct parts of a crate in parallel and then stitch those parts together in a final step. This is very similar to a traditional compiler & linker setup.

Advantages

  • The compiler itself could keep its current architecture that is optimized for single-threaded execution. This sidesteps the problem of having to either find one architecture that works well for both single- and multi-threaded settings or maintaining two purpose built architectures at the same time.
  • There has to be almost no coordination between the parallel processes, removing lots and lots of complexity from maintenance and reasoning about performance.
  • Using multiple processes potentially scales to multi-machine setups, something that might become relevant for big projects with distributed build systems.
  • The implementation of this feature can be confined to a small number of special modules instead of touching almost every aspect of the compiler.
  • If low memory consumption instead of short compile times is the priority then compiling parts serially instead of in parallel would reduce peak memory usage (as @Zoxc pointed out below).

Disadvantages

  • Overall, more redundant work will be done for compiling a single crate. Parsing, macro expansion, and coherence checking (to name a few) will be re-done by every process. Things that heavily rely on caching, like trait selection, will have to start from an empty cache for each process. (Note though that each individual process can run in incremental mode.)
  • Doing redundant things in parallel is likely to increase peak memory consumption.
  • The stitching phase does not work very well with our existing crate metadata format.
  • Error messages would have to be handled specially in order to avoid interleaving and duplication.

Conclusion

I am not particularly advocating for following this approach. This issue is meant to provide input for a wider discussion on how to bring more parallelism to the compilation process. This approach is kind of brute-force. However, I have to say, after thinking about it a little I am surprised to actually find it viable :)

cc @rust-lang/compiler

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-concurrencyArea: ConcurrencyA-parallel-compilerArea: parallel compilerA-processArea: `std::process` and `std::env`C-enhancementCategory: An issue proposing an enhancement or a PR with one.I-compilememIssue: Problems and improvements with respect to memory usage during compilation.I-compiletimeIssue: Problems and improvements with respect to compile times.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions