Skip to content

Commit 84878ee

Browse files
committed
Add cachegrind runtime profiler
1 parent 42410f7 commit 84878ee

File tree

3 files changed

+69
-18
lines changed

3 files changed

+69
-18
lines changed

collector/src/bin/collector.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ use tokio::runtime::Runtime;
3030

3131
use collector::compile::execute::bencher::BenchProcessor;
3232
use collector::compile::execute::profiler::{ProfileProcessor, Profiler};
33+
use collector::runtime::profile_runtime;
3334
use collector::runtime::{
34-
bench_runtime, prepare_runtime_benchmark_suite, profile_runtime, runtime_benchmark_dir,
35-
BenchmarkFilter, BenchmarkSuite, BenchmarkSuiteCompilation, CargoIsolationMode,
35+
bench_runtime, prepare_runtime_benchmark_suite, runtime_benchmark_dir, BenchmarkFilter,
36+
BenchmarkSuite, BenchmarkSuiteCompilation, CargoIsolationMode, RuntimeProfiler,
3637
DEFAULT_RUNTIME_ITERATIONS,
3738
};
3839
use collector::toolchain::{
@@ -496,8 +497,11 @@ enum Commands {
496497

497498
/// Profiles a runtime benchmark.
498499
ProfileRuntime {
499-
#[command(flatten)]
500-
local: LocalOptions,
500+
/// Profiler to use
501+
profiler: RuntimeProfiler,
502+
503+
/// The path to the local rustc used to compile the runtime benchmark
504+
rustc: String,
501505

502506
/// Name of the benchmark that should be profiled
503507
benchmark: String,
@@ -682,15 +686,20 @@ fn main_result() -> anyhow::Result<i32> {
682686
run_benchmarks(&mut rt, conn, shared, None, Some(config))?;
683687
Ok(0)
684688
}
685-
Commands::ProfileRuntime { local, benchmark } => {
686-
let toolchain = get_local_toolchain_for_runtime_benchmarks(&local, &target_triple)?;
689+
Commands::ProfileRuntime {
690+
profiler,
691+
rustc,
692+
benchmark,
693+
} => {
694+
let toolchain =
695+
get_local_toolchain(&[Profile::Opt], &rustc, None, None, None, "", target_triple)?;
687696
let suite = prepare_runtime_benchmark_suite(
688697
&toolchain,
689698
&runtime_benchmark_dir,
690699
CargoIsolationMode::Cached,
691700
)?
692701
.suite;
693-
profile_runtime(suite, &benchmark)?;
702+
profile_runtime(profiler, suite, &benchmark)?;
694703
Ok(0)
695704
}
696705
Commands::BenchLocal {

collector/src/runtime/mod.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@ pub use benchmark::{
1414
use database::{ArtifactIdNumber, CollectionId, Connection};
1515

1616
use crate::utils::git::get_rustc_perf_commit;
17-
use crate::{run_command, run_command_with_output, CollectorCtx};
17+
use crate::{run_command_with_output, CollectorCtx};
1818

1919
mod benchmark;
20+
mod profile;
21+
22+
pub use profile::{profile_runtime, RuntimeProfiler};
2023

2124
pub const DEFAULT_RUNTIME_ITERATIONS: u32 = 5;
2225

@@ -106,16 +109,6 @@ pub async fn bench_runtime(
106109
Ok(())
107110
}
108111

109-
pub fn profile_runtime(suite: BenchmarkSuite, benchmark: &str) -> anyhow::Result<()> {
110-
let Some(group) = suite.get_group_by_benchmark(benchmark) else {
111-
return Err(anyhow::anyhow!("Benchmark `{benchmark}` not found"));
112-
};
113-
let mut cmd = prepare_command(&group.binary);
114-
cmd.arg("profile").arg(benchmark);
115-
run_command(&mut cmd)?;
116-
Ok(())
117-
}
118-
119112
/// Prepares a command for execution, adding some shared flags.
120113
fn prepare_command<S: AsRef<OsStr>>(binary: S) -> Command {
121114
// Turn off ASLR

collector/src/runtime/profile.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use std::fs::create_dir_all;
2+
use std::path::Path;
3+
use std::process::{Command, Stdio};
4+
5+
use anyhow::Context;
6+
7+
use crate::command_output;
8+
use crate::runtime::BenchmarkSuite;
9+
10+
#[derive(Clone, Debug, clap::ValueEnum)]
11+
pub enum RuntimeProfiler {
12+
Cachegrind,
13+
}
14+
15+
pub fn profile_runtime(
16+
profiler: RuntimeProfiler,
17+
suite: BenchmarkSuite,
18+
benchmark: &str,
19+
) -> anyhow::Result<()> {
20+
let Some(group) = suite.get_group_by_benchmark(benchmark) else {
21+
return Err(anyhow::anyhow!("Benchmark `{benchmark}` not found"));
22+
};
23+
24+
let result_dir = Path::new("results");
25+
create_dir_all(result_dir)?;
26+
27+
let (mut cmd, out_file) = match profiler {
28+
RuntimeProfiler::Cachegrind => {
29+
let out_file = result_dir.join(format!("cgout-{benchmark}"));
30+
let mut cmd = Command::new("valgrind");
31+
cmd.arg("--tool=cachegrind")
32+
.arg("--branch-sim=no")
33+
.arg("--cache-sim=no")
34+
.arg(format!("--cachegrind-out-file={}", out_file.display()));
35+
(cmd, out_file)
36+
}
37+
};
38+
cmd.stdin(Stdio::null());
39+
40+
cmd.arg(&group.binary).arg("profile").arg(benchmark);
41+
command_output(&mut cmd).context("Cannot run profiler")?;
42+
43+
println!(
44+
"Profiling complete, result can be found in `{}`",
45+
out_file.display()
46+
);
47+
48+
Ok(())
49+
}

0 commit comments

Comments
 (0)