This repository has no description
1use std::sync::Arc;
2use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
3use std::time::Instant;
4
5#[global_allocator]
6static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
7
8const PAGE: u64 = 4096;
9
10fn rss_bytes() -> u64 {
11 let statm = std::fs::read_to_string("/proc/self/statm").unwrap();
12 statm
13 .split_whitespace()
14 .nth(1)
15 .and_then(|pages| pages.parse::<u64>().ok())
16 .map(|pages| pages * PAGE)
17 .unwrap()
18}
19
20fn vm_hwm_bytes() -> u64 {
21 let status = std::fs::read_to_string("/proc/self/status").unwrap();
22 status
23 .lines()
24 .find_map(|line| line.strip_prefix("VmHWM:"))
25 .and_then(|rest| rest.split_whitespace().next())
26 .and_then(|kb| kb.parse::<u64>().ok())
27 .map(|kb| kb * 1024)
28 .unwrap()
29}
30
31fn mib(bytes: u64) -> u64 {
32 bytes / (1024 * 1024)
33}
34
35fn main() {
36 let pack_path = std::path::PathBuf::from(
37 std::env::args()
38 .nth(1)
39 .expect("usage: ingest_mem <pack-file>"),
40 );
41
42 let pack_size = std::fs::metadata(&pack_path).map(|m| m.len()).unwrap_or(0);
43 println!(
44 "pack: {} MiB on disk, streamed not resident",
45 mib(pack_size)
46 );
47 println!(
48 "governor: {} threads, {}",
49 knot_resource::threads().get(),
50 knot_resource::available_bytes()
51 .map(|bytes| format!("{} MiB available in cgroup", mib(bytes.get())))
52 .unwrap_or_else(|| "unconstrained".to_string())
53 );
54
55 let dir = tempfile::tempdir().expect("tempdir");
56 let objects_dir = dir.path().to_path_buf();
57
58 let peak = Arc::new(AtomicU64::new(0));
59 let stop = Arc::new(AtomicBool::new(false));
60 let sampler = {
61 let peak = Arc::clone(&peak);
62 let stop = Arc::clone(&stop);
63 std::thread::spawn(move || {
64 while !stop.load(Ordering::Relaxed) {
65 let now = rss_bytes();
66 peak.fetch_max(now, Ordering::Relaxed);
67 std::thread::sleep(std::time::Duration::from_millis(5));
68 }
69 })
70 };
71
72 let before = rss_bytes();
73 let start = Instant::now();
74 let folded = knot_pack::bench_ingest_fresh(&objects_dir, &pack_path, gix::hash::Kind::Sha1)
75 .expect("ingest");
76 let elapsed = start.elapsed();
77 stop.store(true, Ordering::Relaxed);
78 sampler.join().ok();
79
80 let sampled_peak = peak.load(Ordering::Relaxed);
81 println!("fold engaged: {folded}");
82 println!("took: {:.1}s", elapsed.as_secs_f64());
83 println!("rss before ingest: {} MiB", mib(before));
84 println!("rss sampled peak: {} MiB", mib(sampled_peak));
85 println!("VmHWM, kernel peak: {} MiB", mib(vm_hwm_bytes()));
86}