Skip to content

Commit 0185d8d

Browse files
Share initial build cache across all benchmarks
Previously, each benchmark would rebuild dependencies from scratch, which was somewhat inefficient: many dependencies in Rust are shared amongst crates (e.g., syn, serde). This shares them across all benchmarks. The next step would be to go further, and share between build kinds (e.g., build scripts only need to be built once). But we don't actually have a good way of doing so, so that's left out of scope for now.
1 parent a22b1b2 commit 0185d8d

File tree

1 file changed

+34
-25
lines changed

1 file changed

+34
-25
lines changed

collector/src/execute.rs

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,8 @@ impl Profiler {
198198

199199
struct CargoProcess<'a> {
200200
compiler: Compiler<'a>,
201-
cwd: &'a Path,
201+
src_dir: &'a Path,
202+
target_directory: &'a Path,
202203
build_kind: BuildKind,
203204
incremental: bool,
204205
processor_etc: Option<(&'a mut dyn Processor, RunKind, &'a str, Option<&'a Patch>)>,
@@ -227,7 +228,7 @@ impl<'a> CargoProcess<'a> {
227228
self
228229
}
229230

230-
fn base_command(&self, cwd: &Path, subcommand: &str) -> Command {
231+
fn base_command(&self, subcommand: &str) -> Command {
231232
let mut cmd = Command::new(Path::new(self.compiler.cargo));
232233
cmd
233234
// Not all cargo invocations (e.g. `cargo clean`) need all of these
@@ -239,7 +240,9 @@ impl<'a> CargoProcess<'a> {
239240
// and any in-tree dependencies, and we don't want that; it wastes
240241
// time.
241242
.env("CARGO_INCREMENTAL", "0")
242-
.current_dir(cwd)
243+
.current_dir(self.src_dir)
244+
.arg("--target-dir")
245+
.arg(self.target_directory)
243246
.arg(subcommand)
244247
.arg("--manifest-path")
245248
.arg(&self.manifest_path);
@@ -250,10 +253,10 @@ impl<'a> CargoProcess<'a> {
250253
cmd
251254
}
252255

253-
fn get_pkgid(&self, cwd: &Path) -> anyhow::Result<String> {
254-
let mut pkgid_cmd = self.base_command(cwd, "pkgid");
256+
fn get_pkgid(&self) -> anyhow::Result<String> {
257+
let mut pkgid_cmd = self.base_command("pkgid");
255258
let out = command_output(&mut pkgid_cmd)
256-
.with_context(|| format!("failed to obtain pkgid in '{:?}'", cwd))?
259+
.with_context(|| format!("failed to obtain pkgid in '{:?}'", self.src_dir))?
257260
.stdout;
258261
let package_id = str::from_utf8(&out).unwrap();
259262
Ok(package_id.trim().to_string())
@@ -305,8 +308,8 @@ impl<'a> CargoProcess<'a> {
305308
}
306309
};
307310

308-
let mut cmd = self.base_command(self.cwd, subcommand);
309-
cmd.arg("-p").arg(self.get_pkgid(self.cwd)?);
311+
let mut cmd = self.base_command(subcommand);
312+
cmd.arg("-p").arg(self.get_pkgid()?);
310313
match self.build_kind {
311314
BuildKind::Check => {
312315
cmd.arg("--profile").arg("check");
@@ -353,10 +356,10 @@ impl<'a> CargoProcess<'a> {
353356
// in-tree (e.g., in the case of the servo crates there are a lot of
354357
// other components).
355358
if let Some(file) = &self.touch_file {
356-
touch(&self.cwd, Path::new(&file))?;
359+
touch(&self.src_dir, Path::new(&file))?;
357360
} else {
358361
touch_all(
359-
&self.cwd.join(
362+
&self.src_dir.join(
360363
Path::new(&self.manifest_path)
361364
.parent()
362365
.expect("manifest has parent"),
@@ -374,7 +377,7 @@ impl<'a> CargoProcess<'a> {
374377
if self.incremental {
375378
cmd.arg("-C");
376379
let mut incr_arg = std::ffi::OsString::from("incremental=");
377-
incr_arg.push(self.cwd.join("incremental-state"));
380+
incr_arg.push(self.target_directory.join("incremental-state"));
378381
cmd.arg(incr_arg);
379382
}
380383

@@ -388,7 +391,7 @@ impl<'a> CargoProcess<'a> {
388391
if let Some((ref mut processor, run_kind, run_kind_str, patch)) = self.processor_etc {
389392
let data = ProcessOutputData {
390393
name: self.processor_name.clone(),
391-
cwd: self.cwd,
394+
cwd: self.target_directory,
392395
build_kind: self.build_kind,
393396
run_kind,
394397
run_kind_str,
@@ -952,7 +955,8 @@ impl Benchmark {
952955
fn mk_cargo_process<'a>(
953956
&'a self,
954957
compiler: Compiler<'a>,
955-
cwd: &'a Path,
958+
target_directory: &'a Path,
959+
src_dir: &'a Path,
956960
build_kind: BuildKind,
957961
) -> CargoProcess<'a> {
958962
let mut cargo_args = self
@@ -973,7 +977,8 @@ impl Benchmark {
973977
CargoProcess {
974978
compiler,
975979
processor_name: self.name.clone(),
976-
cwd,
980+
target_directory,
981+
src_dir,
977982
build_kind,
978983
incremental: false,
979984
processor_etc: None,
@@ -1013,9 +1018,11 @@ impl Benchmark {
10131018
}
10141019

10151020
eprintln!("Preparing {}", self.name);
1021+
1022+
// These directories are *target* directories.
10161023
let build_kind_dirs = build_kinds
10171024
.iter()
1018-
.map(|kind| Ok((*kind, self.make_temp_dir(&self.path)?)))
1025+
.map(|kind| Ok((*kind, TempDir::new()?, self.make_temp_dir(&self.path)?)))
10191026
.collect::<anyhow::Result<Vec<_>>>()?;
10201027

10211028
// In parallel (but with a limit to the number of CPUs), prepare all
@@ -1041,10 +1048,10 @@ impl Benchmark {
10411048
// target-directory global lock during compilation.
10421049
crossbeam_utils::thread::scope::<_, anyhow::Result<()>>(|s| {
10431050
let server = jobserver::Client::new(num_cpus::get()).context("jobserver::new")?;
1044-
for (build_kind, prep_dir) in &build_kind_dirs {
1051+
for (build_kind, target_dir, src_dir) in &build_kind_dirs {
10451052
let server = server.clone();
10461053
s.spawn::<_, anyhow::Result<()>>(move |_| {
1047-
self.mk_cargo_process(compiler, prep_dir.path(), *build_kind)
1054+
self.mk_cargo_process(compiler, target_dir.path(), src_dir.path(), *build_kind)
10481055
.jobserver(server)
10491056
.run_rustc(false)?;
10501057
Ok(())
@@ -1054,7 +1061,7 @@ impl Benchmark {
10541061
})
10551062
.unwrap()?;
10561063

1057-
for (build_kind, prep_dir) in build_kind_dirs {
1064+
for (build_kind, target_dir, src_dir) in build_kind_dirs {
10581065
eprintln!("Running {}: {:?} + {:?}", self.name, build_kind, run_kinds);
10591066

10601067
// We want at least two runs for all benchmarks (since we run
@@ -1070,12 +1077,14 @@ impl Benchmark {
10701077
}
10711078
}
10721079
log::debug!("Benchmark iteration {}/{}", i + 1, iterations);
1073-
let timing_dir = self.make_temp_dir(prep_dir.path())?;
1074-
let cwd = timing_dir.path();
1080+
let target_dir = self.make_temp_dir(target_dir.path())?;
1081+
let target_dir = target_dir.path();
1082+
let src_dir = self.make_temp_dir(src_dir.path())?;
1083+
let src_dir = src_dir.path();
10751084

10761085
// A full non-incremental build.
10771086
if run_kinds.contains(&RunKind::Full) {
1078-
self.mk_cargo_process(compiler, cwd, build_kind)
1087+
self.mk_cargo_process(compiler, target_dir, src_dir, build_kind)
10791088
.processor(processor, RunKind::Full, "Full", None)
10801089
.run_rustc(true)?;
10811090
}
@@ -1088,15 +1097,15 @@ impl Benchmark {
10881097
|| run_kinds.contains(&RunKind::IncrUnchanged)
10891098
|| run_kinds.contains(&RunKind::IncrPatched)
10901099
{
1091-
self.mk_cargo_process(compiler, cwd, build_kind)
1100+
self.mk_cargo_process(compiler, target_dir, src_dir, build_kind)
10921101
.incremental(true)
10931102
.processor(processor, RunKind::IncrFull, "IncrFull", None)
10941103
.run_rustc(true)?;
10951104
}
10961105

10971106
// An incremental build with no changes (fastest incremental case).
10981107
if run_kinds.contains(&RunKind::IncrUnchanged) {
1099-
self.mk_cargo_process(compiler, cwd, build_kind)
1108+
self.mk_cargo_process(compiler, target_dir, src_dir, build_kind)
11001109
.incremental(true)
11011110
.processor(processor, RunKind::IncrUnchanged, "IncrUnchanged", None)
11021111
.run_rustc(true)?;
@@ -1105,12 +1114,12 @@ impl Benchmark {
11051114
if run_kinds.contains(&RunKind::IncrPatched) {
11061115
for (i, patch) in self.patches.iter().enumerate() {
11071116
log::debug!("applying patch {}", patch.name);
1108-
patch.apply(cwd).map_err(|s| anyhow::anyhow!("{}", s))?;
1117+
patch.apply(src_dir).map_err(|s| anyhow::anyhow!("{}", s))?;
11091118

11101119
// An incremental build with some changes (realistic
11111120
// incremental case).
11121121
let run_kind_str = format!("IncrPatched{}", i);
1113-
self.mk_cargo_process(compiler, cwd, build_kind)
1122+
self.mk_cargo_process(compiler, target_dir, src_dir, build_kind)
11141123
.incremental(true)
11151124
.processor(
11161125
processor,

0 commit comments

Comments
 (0)