1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//! Cold-bake profile target — emits tracing-flame folded stacks for
//! 5 sequential alpine:latest bakes. Used to find where the
//! remaining ~500 ms of B1 cold-bake wall-clock goes after the
//! 0.7.42 perf pass (mimalloc + apple-m4 + sibling-clone).
//!
//! Usage:
//!
//! cargo run --release --example _alpine_bake_profile
//! cargo install inferno # if not yet installed
//! inferno-flamegraph < /tmp/supermachine-alpine-bake.folded \
//! > /tmp/alpine-bake.svg
//! open /tmp/alpine-bake.svg
//!
//! The first bake is a true cold bake (~500 ms expected on M5 Pro).
//! Bakes 2-5 hit the sibling-clone fast path (~15 ms each). Look at
//! the first bake's spans to find where the remaining time goes.
use std::time::Instant;
use supermachine::Image;
use tracing_flame::FlameLayer;
use tracing_subscriber::prelude::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let flame_path = std::env::var("SUPERMACHINE_FLAME_OUT")
.unwrap_or_else(|_| "/tmp/supermachine-alpine-bake.folded".to_owned());
eprintln!("[flame] writing folded stacks → {flame_path}");
let (flame_layer, _guard) = FlameLayer::with_file(&flame_path)?;
tracing_subscriber::registry().with(flame_layer).init();
let suffix = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)?
.as_secs();
for i in 0..5 {
let name = format!("_profile_alpine_{suffix}_{i}");
let t0 = Instant::now();
let _image = Image::builder("alpine:latest")
.with_name(&name)
.with_memory_mib(256)
.with_pull_policy(supermachine::PullPolicy::Missing)
.build()?;
eprintln!("[flame] bake #{i} ({name}): {:?}", t0.elapsed());
}
drop(_guard);
eprintln!(
"[flame] done. Convert with:\n inferno-flamegraph < {flame_path} > /tmp/alpine-bake.svg"
);
Ok(())
}