Skip to content

Parallel frontend compiler support (perf backend only)#2491

Open
heinwol wants to merge 2 commits into
rust-lang:masterfrom
heinwol:par-front-scenario
Open

Parallel frontend compiler support (perf backend only)#2491
heinwol wants to merge 2 commits into
rust-lang:masterfrom
heinwol:par-front-scenario

Conversation

@heinwol

@heinwol heinwol commented Jul 1, 2026

Copy link
Copy Markdown

Supersedes #2421, but only backend (profiler/bencher/database). As said in parent pr, parallel frontend support is implemented as additional dimension with corresponding row added to the database

azhogin and others added 2 commits June 29, 2026 16:52
from andrew.zhogin@gmail.com: 3ffe80f
as proposed by berykubik@gmail.com in
the discussion of the preceding pr
@Kobzol

Kobzol commented Jul 1, 2026

Copy link
Copy Markdown
Member

Thanks for the PR! Let's revert the last commit; the CI failure shows why we need to have a custom environment variable, so that it will also work with a stable Rust compiler.

@heinwol heinwol force-pushed the par-front-scenario branch from 544995b to 4f11ea4 Compare July 1, 2026 14:37
@heinwol

heinwol commented Jul 1, 2026

Copy link
Copy Markdown
Author

I'm not sure I quite like a separate environment variable for that; don't we have a better mechanism? Also, maybe a collector run shouldn't silently revert to single-threaded scenario in an unsupported version, which it currently does, for my understanding? However, it seems like it's a common behavior in collector/src/lib.rs::async fn bench_published_artifact:

// ...
    let profiles = if collector::version_supports_doc(&toolchain.id) {
        vec![Profile::Check, Profile::Debug, Profile::Doc, Profile::Opt]
    } else {
        vec![Profile::Check, Profile::Debug, Profile::Opt]
    };
    let scenarios = if collector::version_supports_incremental(&toolchain.id) {
        Scenario::all()
    } else {
        Scenario::all_non_incr()
    };
    let frontend_threads_counts = if collector::version_supports_parallel_frontend(&toolchain.id) {
        FrontendThreads::default_opts()
    } else {
        vec![FrontendThreads(1)]
    };
// ...

So it might be i'm looking too hard into it...

@Kobzol

Kobzol commented Jul 2, 2026

Copy link
Copy Markdown
Member

bench_published_artifact is only used for benchmarking stable versions of the compiler, which is ~never done locally, and we need to keep compatibility with Rust going all the way back to 1.26.0, so I wouldn't worry about that.

@Kobzol Kobzol left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for separating the PR! Did a first review pass. Adding a new benchmark axis is always cumbersome, as it requires changing many places, and this one is also tricky, because it doesn't have a closed set of values, but is just a number. But in general it looks good, just

Please revert all the site changes, the integration with the frontend and also the job queuing system should be done in a follow-up PR. For now everything on production will just assume frontend count 1.

benchmark.name,
profile,
scenario,
frontend_threads.par_n(),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove the par_n function, it contains a hardcoded string prefix that is then used in several places. That shouldn't belong in the database module.

#[arg(
long = "frontend-threads",
value_delimiter = ',',
default_value = "1,4"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
default_value = "1,4"
default_value = "1"

The default should just be one for now, we don't need to test multiple values by default, it would just make local runs unnecessarily slower.

},
bench_rustc,
targets: vec![job.target().into()],
frontend_threads: FrontendThreads::default_opts(),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
frontend_threads: FrontendThreads::default_opts(),
frontend_threads: FrontendThreads::default_value(),

And also change the default to just [1].

let frontend_threads_counts = if collector::version_supports_parallel_frontend(&toolchain.id) {
FrontendThreads::default_opts()
} else {
vec![FrontendThreads(1)]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this is tricky, because for the old version that doesn't support the flag, we would either:

  • Not pass the RUSTC_THREAD_COUNT at all (which happens now). That works for the old compiler, but if we change the default thread count in the future, then setting --frontend-threads=1 will actually use the default number of threads, which is misleading.
  • Still try to pass -Zthreads=1. That will ensure that we are using the right number of threads, but it will break benchmarking on Rust <1.33.0.

I would suggest changing this to always pass the flag. It is better to break benchmarking on Rust <1.33.0, which likely won't be needed in the near future, than to use an unexpected thread count by mistake.

Comment on lines +412 to +414
if self.frontend_threads.0 != 1 {
cmd.env("RUSTC_THREAD_COUNT", self.frontend_threads.0.to_string());
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if self.frontend_threads.0 != 1 {
cmd.env("RUSTC_THREAD_COUNT", self.frontend_threads.0.to_string());
}
cmd.env("RUSTC_THREAD_COUNT", self.frontend_threads.0.to_string());

.raw()
.prepare(
"select id, crate, profile, scenario, backend, target, metric from pstat_series;",
"select id, crate, profile, scenario, backend, target, metric, frontend_threads from pstat_series;",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"select id, crate, profile, scenario, backend, target, metric, frontend_threads from pstat_series;",
"select id, crate, profile, scenario, backend, target, frontend_threads, metric from pstat_series;",

And everywhere else.

Comment thread database/src/lib.rs
Comment on lines +597 to +598
Metric,
FrontendThreads,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Metric,
FrontendThreads,
FrontendThreads,
Metric,

Comment thread database/src/selector.rs
Comment on lines 195 to 197
metric: Selector<crate::Metric>,
frontend_threads: Selector<FrontendThreads>,
target: Selector<Target>,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
metric: Selector<crate::Metric>,
frontend_threads: Selector<FrontendThreads>,
target: Selector<Target>,
target: Selector<Target>,
frontend_threads: Selector<FrontendThreads>,
metric: Selector<crate::Metric>,

Comment thread database/schema.md
Comment on lines +37 to +39
│ metric │ └──────────┘
│ target |
│ frontend_threads |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
metric │ └──────────┘
│ target |
frontend_threads |
frontend_threads │ └──────────┘
│ target |
metric |

Comment thread database/schema.md
Comment on lines 113 to +114
* **metric** (`text`): the type of metric being collected.
* **frontend_threads** (`text`): Parallel frontend thread count ('-Zthreads=N').

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* **metric** (`text`): the type of metric being collected.
* **frontend_threads** (`text`): Parallel frontend thread count ('-Zthreads=N').
* **frontend_threads** (`text`): Parallel frontend thread count ('-Zthreads=N').
* **metric** (`text`): the type of metric being collected.

Seems like we are missing the target here (pre-existing), could you please add it? Thanks!

@heinwol

heinwol commented Jul 2, 2026

Copy link
Copy Markdown
Author

Thanks for the fast yet sizable review! I'm sorry for calling out for you so early; i'm not sure this pr is quite review-ready. I'll try to resolve what you commented for now and then dive more into how this works! As until now all i did is brainless-ish renaming, lol

@Kobzol

Kobzol commented Jul 2, 2026

Copy link
Copy Markdown
Member

To be fair, adding a new benchmark axis mostly involves a lot of brainless-ish renaming :) I think that the PR is mostly good to go, though it will require a couple of follow-up PRs to:

  1. Add integration in the website backend and frontend
  2. Modify the job queue to be able to distinguish that different jobs can have different frontend thread counts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants