Skip to content

Reboot Parallel Rustc WG Proposal #567

Closed
@SparrowLii

Description

@SparrowLii

Proposal

Reboot the parallel compilation working group, make the current parallel compiler truly available to Rust users, and improve the functions and supporting facilities of the parallel compiler.

Motivation

Parallelization is an important way to improve the efficiency of the compiler. The parallel rustc working group in the compiler team is responsible for the parallelization of the compiler. At current the working group has been stagnant for a long time due to the exit of the main developer.

Yet the parallel compiler still has considerable value and potential. In the previous build test, quite a few parts of the test set achieved huge improvements in wall-time. And many parts of the compilation process, e.g. expansion, have the potential to be parallelized.

Design

Make the nightly compiler able to parallelize

Currently users can only use the parallel compiler by installing rust locally from source code with setting parallel-compiler = true in config.toml. Ideally, the user can choose whether to compile in parallel by setting -Zthread=n. The biggest problem here is efficiency of parallel-queries system. Enable parallel-queries will result in about 5% regressive compared to non-parallel mode when setting -Zthread=1.

Closing this performance gap as much as possible and enabling parallel-queries by default is the working group's main job. We can optimize the compilation process according to the following strategies to reduce performance regression:

  1. Prioritize the refactoring of the code implementation to reduce the number of calls to Lock::lock(). e.g. commit, #101313, #99702
  2. If 1 does not work well, use GAT to make the two modes(parallel and non-parallel) use different implementations for Lock. This relatively increases the size of the rustc binary, and needs some extra efforts to ensure threads safety. Fortunately, we only need to make such changes to a small part of the code. From the results of the experimental PR, doing so when the query system creates new dep-nodes and accesses the query cache solves nearly half of the regression.

On the other hand, considering the regressive may not be completely eliminated (at least without doing a large-scale refactoring of the compiler code or making it too complex), we need to decide the regressive bound in single-threaded mode. We can discuss this with the rustc-perf working group.

Measure rustc's performance in a multi-threaded environment

Improve rustc-perf's support for parallel compilers. The total instruction count is difficult to reflect the real compilation efficiency in a multi-threaded environment. We should implement a different counting strategy, such as having only one of the running threads increases the counter.

Special benchmarks for multi-threaded environments need to be added, too. Such as the number of locks and blocking time.

This part of the work is also very important, which makes us able to measure the benefits of parallel compilers to determine the acceptable refressive bound in single-threaded mode.

Test for parallel compiler

Most of the UI tests in the parallel environment have been fixed, see here. But these UI tests are only for -Zthreads=1, and not for using more threads. And based on some previous experience, -Zthread=n does cause ICE issues in real builds. We need to collect and fix these problems.

On the other hand, multithreading can also result in diagnostics not being output in a deterministic order. We may need to do some implementation to solve it, such as changing from "outputting the diagnostics immediately when the compilation fails" to "collecting all the diagnostics first, sorting and then outputting". The order of diagnostics also needs to be determined, such as getting the index of the current rayon iterator task and writing it to each diagnostic.

Deepen compiler parallelism

Currently the only stage of the compiler that is already parallel is codegen. The part that is being improved is parallel-queries. In addition to this, there are other parts of the compiler that also have the potential to be parallelized.

Lex parsing, macro expansion, and name resolving have considerable potential for parallelization. These partial functions are relatively independent to other parts and do not rely on the query system.

Alternatives

Keep the current implementation based on #[cfg(parallel_compiler)] conditional compilation, and let other community components provide parallelized compilers. For example, allowing users to switch to a parallelized compiler version through the rustup tool.

Considering that the efficiency of parallel query is the current bottleneck, this approach can allow general users to fetch the parallel compiler more quickly.

Working group members

@cjgillot, @bjorn3, @nnethercote, @Kobzol and @SparrowLii would like to be part of the rebooted working group.

Welcome to join if you are also interested in this work!

Mentors or Reviewers

@cjgillot @bjorn3 @Kobzol are willing to do the review work. Very grateful for their help!

Process

The main points of the Major Change Process are as follows:

  • File an issue describing the proposal.
  • A compiler team member or contributor who is knowledgeable in the area can second by writing @rustbot second.
    • Finding a "second" suffices for internal changes. If however, you are proposing a new public-facing feature, such as a -C flag, then full team check-off is required.
    • Compiler team members can initiate a check-off via @rfcbot fcp merge on either the MCP or the PR.
  • Once an MCP is seconded, the Final Comment Period begins. If no objections are raised after 10 days, the MCP is considered approved.

You can read more about Major Change Proposals on forge.

Comments

This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-compilerAdd this label so rfcbot knows to poll the compiler teammajor-changeA proposal to make a major change to rustcmajor-change-acceptedA major change proposal that was accepted

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions