Skip to content

Commit 82b00ec

Browse files
Rollup merge of #81536 - tgnottingham:time-passes-rss, r=oli-obk
Indicate both start and end of pass RSS in time-passes output Previously, only the end of pass RSS was indicated. This could easily lead one to believe that the change in RSS from one pass to the next was attributable to the second pass, when in fact it occurred between the end of the first pass and the start of the second. Also, improve alignment of columns. Sample of output: ``` time: 0.739; rss: 607MB -> 637MB item_types_checking time: 8.429; rss: 637MB -> 775MB item_bodies_checking time: 11.063; rss: 470MB -> 775MB type_check_crate time: 0.232; rss: 775MB -> 777MB match_checking time: 0.139; rss: 777MB -> 779MB liveness_and_intrinsic_checking time: 0.372; rss: 775MB -> 779MB misc_checking_2 time: 8.188; rss: 779MB -> 1019MB MIR_borrow_checking time: 0.062; rss: 1019MB -> 1021MB MIR_effect_checking ```
2 parents 39ea347 + 849dc1a commit 82b00ec

File tree

4 files changed

+68
-28
lines changed

4 files changed

+68
-28
lines changed

compiler/rustc_codegen_cranelift/src/bin/cg_clif.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ extern crate rustc_interface;
66
extern crate rustc_session;
77
extern crate rustc_target;
88

9-
use rustc_data_structures::profiling::print_time_passes_entry;
9+
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
1010
use rustc_interface::interface;
1111
use rustc_session::config::ErrorOutputType;
1212
use rustc_session::early_error;
@@ -39,7 +39,8 @@ impl rustc_driver::Callbacks for CraneliftPassesCallbacks {
3939
}
4040

4141
fn main() {
42-
let start = std::time::Instant::now();
42+
let start_time = std::time::Instant::now();
43+
let start_rss = get_resident_set_size();
4344
rustc_driver::init_rustc_env_logger();
4445
let mut callbacks = CraneliftPassesCallbacks::default();
4546
rustc_driver::install_ice_hook();
@@ -61,7 +62,11 @@ fn main() {
6162
})));
6263
run_compiler.run()
6364
});
64-
// The extra `\t` is necessary to align this label with the others.
65-
print_time_passes_entry(callbacks.time_passes, "\ttotal", start.elapsed());
65+
66+
if callbacks.time_passes {
67+
let end_rss = get_resident_set_size();
68+
print_time_passes_entry("total", start_time.elapsed(), start_rss, end_rss);
69+
}
70+
6671
std::process::exit(exit_code)
6772
}

compiler/rustc_codegen_ssa/src/base.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::{CachedModuleCodegen, CrateInfo, MemFlags, ModuleCodegen, ModuleKind}
1212

1313
use rustc_attr as attr;
1414
use rustc_data_structures::fx::FxHashMap;
15-
use rustc_data_structures::profiling::print_time_passes_entry;
15+
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
1616
use rustc_data_structures::sync::{par_iter, ParallelIterator};
1717
use rustc_hir as hir;
1818
use rustc_hir::def_id::{LocalDefId, LOCAL_CRATE};
@@ -595,6 +595,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
595595
let mut cgu_reuse = Vec::new();
596596
let mut pre_compiled_cgus: Option<FxHashMap<usize, _>> = None;
597597
let mut total_codegen_time = Duration::new(0, 0);
598+
let start_rss = tcx.sess.time_passes().then(|| get_resident_set_size());
598599

599600
for (i, cgu) in codegen_units.iter().enumerate() {
600601
ongoing_codegen.wait_for_signal_to_codegen_item();
@@ -669,7 +670,16 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
669670

670671
// Since the main thread is sometimes blocked during codegen, we keep track
671672
// -Ztime-passes output manually.
672-
print_time_passes_entry(tcx.sess.time_passes(), "codegen_to_LLVM_IR", total_codegen_time);
673+
if tcx.sess.time_passes() {
674+
let end_rss = get_resident_set_size();
675+
676+
print_time_passes_entry(
677+
"codegen_to_LLVM_IR",
678+
total_codegen_time,
679+
start_rss.unwrap(),
680+
end_rss,
681+
);
682+
}
673683

674684
ongoing_codegen.check_for_errors(tcx.sess);
675685

compiler/rustc_data_structures/src/profiling.rs

+38-18
Original file line numberDiff line numberDiff line change
@@ -555,13 +555,16 @@ impl<'a> TimingGuard<'a> {
555555

556556
#[must_use]
557557
pub struct VerboseTimingGuard<'a> {
558-
start_and_message: Option<(Instant, String)>,
558+
start_and_message: Option<(Instant, Option<usize>, String)>,
559559
_guard: TimingGuard<'a>,
560560
}
561561

562562
impl<'a> VerboseTimingGuard<'a> {
563563
pub fn start(message: Option<String>, _guard: TimingGuard<'a>) -> Self {
564-
VerboseTimingGuard { _guard, start_and_message: message.map(|msg| (Instant::now(), msg)) }
564+
VerboseTimingGuard {
565+
_guard,
566+
start_and_message: message.map(|msg| (Instant::now(), get_resident_set_size(), msg)),
567+
}
565568
}
566569

567570
#[inline(always)]
@@ -573,25 +576,42 @@ impl<'a> VerboseTimingGuard<'a> {
573576

574577
impl Drop for VerboseTimingGuard<'_> {
575578
fn drop(&mut self) {
576-
if let Some((start, ref message)) = self.start_and_message {
577-
print_time_passes_entry(true, &message[..], start.elapsed());
579+
if let Some((start_time, start_rss, ref message)) = self.start_and_message {
580+
let end_rss = get_resident_set_size();
581+
print_time_passes_entry(&message[..], start_time.elapsed(), start_rss, end_rss);
578582
}
579583
}
580584
}
581585

582-
pub fn print_time_passes_entry(do_it: bool, what: &str, dur: Duration) {
583-
if !do_it {
584-
return;
585-
}
586-
587-
let mem_string = match get_resident() {
588-
Some(n) => {
589-
let mb = n as f64 / 1_000_000.0;
590-
format!("; rss: {}MB", mb.round() as usize)
586+
pub fn print_time_passes_entry(
587+
what: &str,
588+
dur: Duration,
589+
start_rss: Option<usize>,
590+
end_rss: Option<usize>,
591+
) {
592+
let rss_to_mb = |rss| (rss as f64 / 1_000_000.0).round() as usize;
593+
594+
let mem_string = match (start_rss, end_rss) {
595+
(Some(start_rss), Some(end_rss)) => {
596+
// It's tempting to add the change in RSS from start to end, but its somewhat confusing
597+
// and misleading when looking at time-passes output. Consider two adjacent entries:
598+
//
599+
// time: 10.000; rss start: 1000MB, end: 1000MB, change: 0MB pass1
600+
// time: 5.000; rss start: 2000MB, end: 2000MB, change: 0MB pass2
601+
//
602+
// If you're looking for jumps in RSS based on the change column, you miss the fact
603+
// that a 1GB jump happened between pass1 and pass2 (supposing pass1 and pass2 actually
604+
// occur sequentially and pass1 isn't just nested within pass2). It's easy to imagine
605+
// someone missing this or being confused by the fact that the change is zero.
606+
607+
format!("; rss: {:>5}MB -> {:>5}MB", rss_to_mb(start_rss), rss_to_mb(end_rss))
591608
}
592-
None => String::new(),
609+
(Some(start_rss), None) => format!("; rss start: {:>5}MB", rss_to_mb(start_rss)),
610+
(None, Some(end_rss)) => format!("; rss end: {:5>}MB", rss_to_mb(end_rss)),
611+
(None, None) => String::new(),
593612
};
594-
println!("time: {}{}\t{}", duration_to_secs_str(dur), mem_string, what);
613+
614+
println!("time: {:>7}{}\t{}", duration_to_secs_str(dur), mem_string, what);
595615
}
596616

597617
// Hack up our own formatting for the duration to make it easier for scripts
@@ -603,7 +623,7 @@ pub fn duration_to_secs_str(dur: std::time::Duration) -> String {
603623
// Memory reporting
604624
cfg_if! {
605625
if #[cfg(windows)] {
606-
fn get_resident() -> Option<usize> {
626+
pub fn get_resident_set_size() -> Option<usize> {
607627
use std::mem::{self, MaybeUninit};
608628
use winapi::shared::minwindef::DWORD;
609629
use winapi::um::processthreadsapi::GetCurrentProcess;
@@ -621,7 +641,7 @@ cfg_if! {
621641
}
622642
}
623643
} else if #[cfg(unix)] {
624-
fn get_resident() -> Option<usize> {
644+
pub fn get_resident_set_size() -> Option<usize> {
625645
let field = 1;
626646
let contents = fs::read("/proc/self/statm").ok()?;
627647
let contents = String::from_utf8(contents).ok()?;
@@ -630,7 +650,7 @@ cfg_if! {
630650
Some(npages * 4096)
631651
}
632652
} else {
633-
fn get_resident() -> Option<usize> {
653+
pub fn get_resident_set_size() -> Option<usize> {
634654
None
635655
}
636656
}

compiler/rustc_driver/src/lib.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub extern crate rustc_plugin_impl as plugin;
1616

1717
use rustc_ast as ast;
1818
use rustc_codegen_ssa::{traits::CodegenBackend, CodegenResults};
19-
use rustc_data_structures::profiling::print_time_passes_entry;
19+
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
2020
use rustc_data_structures::sync::SeqCst;
2121
use rustc_errors::registry::{InvalidErrorCode, Registry};
2222
use rustc_errors::{ErrorReported, PResult};
@@ -1312,7 +1312,8 @@ pub fn init_env_logger(env: &str) {
13121312
}
13131313

13141314
pub fn main() -> ! {
1315-
let start = Instant::now();
1315+
let start_time = Instant::now();
1316+
let start_rss = get_resident_set_size();
13161317
init_rustc_env_logger();
13171318
let mut callbacks = TimePassesCallbacks::default();
13181319
install_ice_hook();
@@ -1330,7 +1331,11 @@ pub fn main() -> ! {
13301331
.collect::<Vec<_>>();
13311332
RunCompiler::new(&args, &mut callbacks).run()
13321333
});
1333-
// The extra `\t` is necessary to align this label with the others.
1334-
print_time_passes_entry(callbacks.time_passes, "\ttotal", start.elapsed());
1334+
1335+
if callbacks.time_passes {
1336+
let end_rss = get_resident_set_size();
1337+
print_time_passes_entry("total", start_time.elapsed(), start_rss, end_rss);
1338+
}
1339+
13351340
process::exit(exit_code)
13361341
}

0 commit comments

Comments
 (0)