//! `meter-cmd` — a `time`-like energy bracket: the machine's energy over the //! execution of an external command, labelled by how it was obtained. //! //! Where the meter reads hardware counters, the span is a measurement, and an //! idle baseline of equal length gives the workload's marginal draw. The //! counters are machine-wide (not process-scoped) — that caveat is printed, //! not hidden: on a quiet machine, `work − idle` approximates the workload. //! Where the meter could only estimate (no live hardware counter — on Apple //! Silicon, see `ioreport_status()`), the span is wall-clock × TDP, printed //! with its provenance. A `work − idle` difference of two such estimates is //! not the workload's share of anything, so none is printed. //! //! Run: `cargo run --release --example meter_cmd -- [args…]` use sandbox_meter::{IoReportStatus, Measurement, PowerMeter}; use std::process::Command; /// How a span's figure was obtained, from its own records. fn obtained(m: &Measurement) -> &'static str { if m.fully_measured() { "hardware-measured" } else if m.devices.iter().all(|d| d.measured_uj.is_none()) { "estimated" } else { "partly estimated" } } /// Each record's provenance, e.g. `Cpu Estimator`. fn grades(m: &Measurement) -> String { m.devices .iter() .map(|d| format!("{:?} {}", d.class, d.provenance.label())) .collect::>() .join(", ") } fn main() { let args: Vec = std::env::args().skip(1).collect(); let (program, rest) = args.split_first().expect("usage: meter-cmd [args…]"); let mut meter = PowerMeter::detect(); let ioreport = sandbox_meter::ioreport_status(); eprintln!( "meter-cmd: probes [{}]", if meter.is_hardware() { meter.sources().join(", ") } else if ioreport != IoReportStatus::Unavailable { // Apple Silicon: say why the SoC counters were declined. format!("none — estimator fallback ({ioreport})") } else { "none — estimator fallback".into() } ); // measure the command (the workload inherits this process's environment) let (status, work) = meter.measure(|| { Command::new(program).args(rest).status().expect("spawn command") }); let work_j = work.total_uj() as f64 / 1e6; println!("\n== meter-cmd result =="); println!("command exited: {status}"); println!("wall: {:.1} s", work.wall.as_secs_f64()); println!("machine (work): {work_j:.3} J ({:.2} W avg) [{}]", work.avg_watts(), grades(&work)); if work.fully_measured() { // An idle baseline of the same wall length, for the marginal figure. let dur = work.wall; let ((), idle) = meter.measure(|| std::thread::sleep(dur)); let idle_j = idle.total_uj() as f64 / 1e6; println!("machine (idle): {idle_j:.3} J ({:.2} W avg) [{}]", idle.avg_watts(), grades(&idle)); if !idle.fully_measured() { println!("marginal: none — the idle baseline was {}, not a reading", obtained(&idle)); } else if work_j > idle_j { println!( "marginal: {:.3} J (work − idle over machine-wide counters: the workload's \ draw, on a quiet machine)", work_j - idle_j ); } else { // Never a floored 0 for work that ran: the counters did not // resolve this workload above the idle draw. println!( "marginal: not resolved — work ({work_j:.3} J) did not exceed idle ({idle_j:.3} J) \ on machine-wide counters" ); } } else { println!( "estimate: {work_j:.3} J ({}) — wall-clock × TDP, not a reading; no work − idle \ marginal, since two such estimates differ only by duration", obtained(&work) ); } println!("source: {} ({})", work.source, obtained(&work)); }