Skip to content

Commit 3ed6e53

Browse files
authored
Merge pull request #1515 from Kobzol/runtime-db-sqlite
Store runtime benchmark results into SQLite
2 parents 1aa03a4 + 3db1557 commit 3ed6e53

File tree

15 files changed

+215
-79
lines changed

15 files changed

+215
-79
lines changed

collector/src/bin/collector.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ fn bench(
118118
}
119119
let mut tx = rt.block_on(conn.transaction());
120120
let (supports_stable, category) = category.db_representation();
121-
rt.block_on(tx.conn().record_benchmark(
121+
rt.block_on(tx.conn().record_compile_benchmark(
122122
&benchmark_name.0,
123123
Some(supports_stable),
124124
category,
@@ -571,6 +571,9 @@ enum Commands {
571571
/// How many iterations of each benchmark should be executed.
572572
#[clap(long, default_value = "5")]
573573
iterations: u32,
574+
575+
#[clap(flatten)]
576+
db: DbOption,
574577
},
575578
/// Benchmarks a local rustc
576579
BenchLocal {
@@ -703,7 +706,11 @@ fn main_result() -> anyhow::Result<i32> {
703706
let target_triple = format!("{}-unknown-linux-gnu", std::env::consts::ARCH);
704707

705708
match args.command {
706-
Commands::BenchRuntimeLocal { local, iterations } => {
709+
Commands::BenchRuntimeLocal {
710+
local,
711+
iterations,
712+
db,
713+
} => {
707714
let toolchain = get_local_toolchain(
708715
&[Profile::Opt],
709716
&local.rustc,
@@ -712,12 +719,17 @@ fn main_result() -> anyhow::Result<i32> {
712719
local.id.as_deref(),
713720
"",
714721
)?;
715-
bench_runtime(
722+
let pool = Pool::open(&db.db);
723+
724+
let fut = bench_runtime(
725+
pool,
726+
ArtifactId::Tag(toolchain.id.clone()),
716727
toolchain,
717728
BenchmarkFilter::new(local.exclude, local.include),
718729
runtime_benchmark_dir,
719730
iterations,
720-
)?;
731+
);
732+
rt.block_on(fut)?;
721733
Ok(0)
722734
}
723735
Commands::BenchLocal {

collector/src/execute/bencher.rs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::execute::{
77
SelfProfileFiles, Stats, Upload,
88
};
99
use crate::toolchain::Compiler;
10-
use anyhow::Context;
10+
use crate::utils::git::get_rustc_perf_commit;
1111
use futures::stream::FuturesUnordered;
1212
use futures::StreamExt;
1313
use std::path::PathBuf;
@@ -81,17 +81,7 @@ impl<'a> BenchProcessor<'a> {
8181
profile: Profile,
8282
stats: (Stats, Option<SelfProfile>, Option<SelfProfileFiles>),
8383
) {
84-
let version = String::from_utf8(
85-
Command::new("git")
86-
.arg("rev-parse")
87-
.arg("HEAD")
88-
.output()
89-
.context("git rev-parse HEAD")
90-
.unwrap()
91-
.stdout,
92-
)
93-
.context("utf8")
94-
.unwrap();
84+
let version = get_rustc_perf_commit();
9585

9686
let collection = self.rt.block_on(self.conn.collection_id(&version));
9787
let profile = match profile {

collector/src/execute/rustc.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
//! having to think about how to deduplicate results.
99
1010
use crate::toolchain::Compiler;
11+
use crate::utils::git::get_rustc_perf_commit;
1112
use anyhow::Context;
1213
use database::ArtifactId;
1314
use std::env;
@@ -140,17 +141,7 @@ fn record(
140141
}
141142
}
142143

143-
let version = String::from_utf8(
144-
Command::new("git")
145-
.arg("rev-parse")
146-
.arg("HEAD")
147-
.output()
148-
.context("git rev-parse HEAD")
149-
.unwrap()
150-
.stdout,
151-
)
152-
.context("utf8")
153-
.unwrap();
144+
let version = get_rustc_perf_commit();
154145
let collection = rt.block_on(conn.collection_id(&version));
155146

156147
for (krate, timing) in timing_data {

collector/src/runtime/benchmark.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ impl BenchmarkSuite {
4545
.count() as u64
4646
}
4747

48-
fn benchmark_names(&self) -> impl Iterator<Item = &str> {
48+
pub fn benchmark_names(&self) -> impl Iterator<Item = &str> {
4949
self.groups
5050
.iter()
5151
.flat_map(|suite| suite.benchmark_names.iter().map(|n| n.as_ref()))

collector/src/runtime/mod.rs

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,38 @@
11
mod benchmark;
22

33
use crate::toolchain::LocalToolchain;
4-
use benchlib::comm::messages::{BenchmarkMessage, BenchmarkResult, BenchmarkStats};
54
use std::io::{BufRead, BufReader};
65
use std::path::{Path, PathBuf};
76
use std::process::{Command, Stdio};
87
use thousands::Separable;
98

9+
use benchlib::comm::messages::{BenchmarkMessage, BenchmarkResult, BenchmarkStats};
1010
pub use benchmark::BenchmarkFilter;
11+
use database::{ArtifactId, ArtifactIdNumber, Connection, Pool};
12+
13+
use crate::utils::git::get_rustc_perf_commit;
1114

1215
/// Perform a series of runtime benchmarks using the provided `rustc` compiler.
1316
/// The runtime benchmarks are looked up in `benchmark_dir`, which is expected to be a path
1417
/// to a Cargo crate. All binaries built by that crate will are expected to be runtime benchmark
1518
/// groups that leverage `benchlib`.
16-
pub fn bench_runtime(
19+
pub async fn bench_runtime(
20+
db: Pool,
21+
artifact_id: ArtifactId,
1722
toolchain: LocalToolchain,
1823
filter: BenchmarkFilter,
1924
benchmark_dir: PathBuf,
2025
iterations: u32,
2126
) -> anyhow::Result<()> {
2227
let suite = benchmark::discover_benchmarks(&toolchain, &benchmark_dir)?;
2328

29+
let conn = db.connection().await;
30+
for benchmark in suite.benchmark_names() {
31+
conn.record_runtime_benchmark(benchmark).await;
32+
}
33+
34+
let artifact_id = conn.artifact_id(&artifact_id).await;
35+
2436
let total_benchmark_count = suite.total_benchmark_count();
2537
let filtered = suite.filtered_benchmark_count(&filter);
2638
println!(
@@ -29,6 +41,8 @@ pub fn bench_runtime(
2941
total_benchmark_count - filtered
3042
);
3143

44+
let rustc_perf_version = get_rustc_perf_commit();
45+
3246
let mut benchmark_index = 0;
3347
for binary in suite.groups {
3448
for message in execute_runtime_benchmark_binary(&binary.binary, &filter, iterations)? {
@@ -48,7 +62,9 @@ pub fn bench_runtime(
4862
benchmark_index,
4963
filtered
5064
);
65+
5166
print_stats(&result);
67+
record_stats(&conn, artifact_id, &rustc_perf_version, result).await;
5268
}
5369
}
5470
}
@@ -57,6 +73,29 @@ pub fn bench_runtime(
5773
Ok(())
5874
}
5975

76+
/// Records the results (stats) of a benchmark into the database.
77+
async fn record_stats(
78+
conn: &Box<dyn Connection>,
79+
artifact_id: ArtifactIdNumber,
80+
rustc_perf_version: &str,
81+
result: BenchmarkResult,
82+
) {
83+
for stat in result.stats {
84+
let collection_id = conn.collection_id(rustc_perf_version).await;
85+
86+
if let Some(value) = stat.instructions {
87+
conn.record_runtime_statistic(
88+
collection_id,
89+
artifact_id,
90+
&result.name,
91+
"instructions:u",
92+
value as f64,
93+
)
94+
.await;
95+
}
96+
}
97+
}
98+
6099
/// Starts executing a single runtime benchmark group defined in a binary crate located in
61100
/// `runtime-benchmarks`. The binary is expected to use benchlib's `BenchmarkGroup` to execute
62101
/// a set of runtime benchmarks and print `BenchmarkMessage`s encoded as JSON, one per line.
@@ -87,8 +126,7 @@ fn execute_runtime_benchmark_binary(
87126

88127
let reader = BufReader::new(stdout);
89128
let iterator = reader.lines().map(|line| {
90-
line.and_then(|line| Ok(serde_json::from_str::<BenchmarkMessage>(&line)?))
91-
.map_err(|err| err.into())
129+
Ok(line.and_then(|line| Ok(serde_json::from_str::<BenchmarkMessage>(&line)?))?)
92130
});
93131
Ok(iterator)
94132
}

collector/src/utils/git.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use anyhow::Context;
2+
use std::process::Command;
3+
4+
pub fn get_rustc_perf_commit() -> String {
5+
String::from_utf8(
6+
Command::new("git")
7+
.arg("rev-parse")
8+
.arg("HEAD")
9+
.output()
10+
.context("git rev-parse HEAD")
11+
.unwrap()
12+
.stdout,
13+
)
14+
.context("utf8")
15+
.unwrap()
16+
}

collector/src/utils/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
pub mod fs;
2+
pub mod git;
23
pub mod read2;

database/src/bin/import-sqlite.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use database::{BenchmarkData, Lookup, Pool};
1+
use database::{CompileBenchmark, Lookup, Pool};
22
use hashbrown::HashMap;
33
use std::collections::HashSet;
44

@@ -25,8 +25,8 @@ async fn main() {
2525
let cid = postgres_conn.collection_id(&cid_name).await;
2626

2727
let mut benchmarks = HashSet::new();
28-
let benchmark_data: HashMap<String, BenchmarkData> = sqlite_conn
29-
.get_benchmarks()
28+
let benchmark_data: HashMap<String, CompileBenchmark> = sqlite_conn
29+
.get_compile_benchmarks()
3030
.await
3131
.into_iter()
3232
.map(|benchmark| (benchmark.name.clone(), benchmark))
@@ -48,7 +48,7 @@ async fn main() {
4848
for &(benchmark, profile, scenario, metric) in sqlite_idx.all_statistic_descriptions() {
4949
if benchmarks.insert(benchmark) {
5050
postgres_conn
51-
.record_benchmark(
51+
.record_compile_benchmark(
5252
benchmark.as_str(),
5353
None,
5454
benchmark_data[benchmark.as_str()].category.clone(),

database/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,7 @@ impl fmt::Display for CollectionId {
748748
}
749749

750750
#[derive(Debug, Clone, Serialize)]
751-
pub struct BenchmarkData {
751+
pub struct CompileBenchmark {
752752
pub name: String,
753753
pub category: String,
754754
}

database/src/pool.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{ArtifactId, ArtifactIdNumber, BenchmarkData};
1+
use crate::{ArtifactId, ArtifactIdNumber, CompileBenchmark};
22
use crate::{CollectionId, Index, Profile, QueuedCommit, Scenario, Step};
33
use chrono::{DateTime, Utc};
44
use hashbrown::HashMap;
@@ -15,7 +15,18 @@ pub trait Connection: Send + Sync {
1515
async fn transaction(&mut self) -> Box<dyn Transaction + '_>;
1616

1717
async fn load_index(&mut self) -> Index;
18-
async fn get_benchmarks(&self) -> Vec<BenchmarkData>;
18+
19+
/// None means that the caller doesn't know; it should be left alone if
20+
/// known or set to false if unknown.
21+
async fn record_compile_benchmark(
22+
&self,
23+
krate: &str,
24+
supports_stable: Option<bool>,
25+
category: String,
26+
);
27+
async fn get_compile_benchmarks(&self) -> Vec<CompileBenchmark>;
28+
29+
async fn record_runtime_benchmark(&self, name: &str);
1930

2031
async fn artifact_by_name(&self, artifact: &str) -> Option<ArtifactId>;
2132

@@ -25,9 +36,7 @@ pub trait Connection: Send + Sync {
2536

2637
async fn collection_id(&self, version: &str) -> CollectionId;
2738
async fn artifact_id(&self, artifact: &ArtifactId) -> ArtifactIdNumber;
28-
/// None means that the caller doesn't know; it should be left alone if
29-
/// known or set to false if unknown.
30-
async fn record_benchmark(&self, krate: &str, supports_stable: Option<bool>, category: String);
39+
3140
async fn record_statistic(
3241
&self,
3342
collection: CollectionId,
@@ -38,6 +47,14 @@ pub trait Connection: Send + Sync {
3847
metric: &str,
3948
value: f64,
4049
);
50+
async fn record_runtime_statistic(
51+
&self,
52+
collection: CollectionId,
53+
artifact: ArtifactIdNumber,
54+
benchmark: &str,
55+
metric: &str,
56+
value: f64,
57+
);
4158
/// Records a self-profile artifact in S3.
4259
///
4360
/// The upload is a separate step (which may fail or be canceled, but that's

0 commit comments

Comments
 (0)