Compare commits

...
Author SHA1 Message Date
Ludovic MarieandClaude Opus 5.5 407b6c48e2 bench: finer streaming spans
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-01 01:15:48 +01:00
Ludovic MarieandClaude Opus 5.5 ddac9a5934 bench: streaming sub-spans
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-01 01:00:12 +01:00
2 changed files with 52 additions and 0 deletions

No files matched your search

+21
View File
@@ -161,3 +161,24 @@ mod tests {
assert!(worked.as_millis() >= 10, "{worked:?} while busy");
}
}
/// Bench only: a span from here to the guard's drop.
pub struct Guard(&'static str, Instant, Option<Duration>);
pub fn guard(name: &'static str) -> Option<Guard> {
enabled().then(|| Guard(name, Instant::now(), thread_cpu()))
}
impl Drop for Guard {
fn drop(&mut self) {
let ms = self.1.elapsed().as_secs_f32() * 1000.0;
let cpu_ms = thread_cpu()
.zip(self.2)
.map_or(ms, |(e, s)| (e - s).as_secs_f32() * 1000.0);
SPANS.with(|s| {
s.borrow_mut().push(Span {
name: self.0,
ms,
cpu_ms,
})
});
}
}
@@ -1240,8 +1240,11 @@ impl Streaming {
let sweep = area != self.scan_area || self.scan_age >= 8;
self.scan_area = area;
self.scan_age = if sweep { 0 } else { self.scan_age + 1 };
let g = crate::spans::guard("st_relight_edits");
self.requeue();
self.relight_edits(world);
drop(g);
let g = crate::spans::guard("st_receive");
let deferred = std::mem::take(&mut self.deferred);
let received = self.shared.done.take();
// Meshes made stale meanwhile, freed with the uploaded ones (`free`).
@@ -1322,6 +1325,8 @@ impl Streaming {
}
}
}
drop(g);
let g = crate::spans::guard("st_sweep");
self.free(stale);
let mut removed = Vec::new();
if sweep {
@@ -1391,10 +1396,16 @@ impl Streaming {
}
self.save_checked_out(written);
}
drop(g);
let g = crate::spans::guard("st_finalize");
drop(g);
let g = crate::spans::guard("st_retain");
let (protos, finishing) = (&self.protos, &self.finishing);
self.decorated.retain(|k| {
protos.contains_key(k) || finishing.contains(k) || world.chunks.contains_key(k)
});
drop(g);
let g = crate::spans::guard("st_finalize");
// Finalize chunks whose neighbourhood is decorated.
let candidates: Vec<(i32, i32)> = self.protos.keys().copied().collect();
for (x, z) in candidates {
@@ -1425,6 +1436,8 @@ impl Streaming {
// Decorate chunks whose 3x3 proto neighbourhood is available, in
// vanilla's order: decoration is order dependent where write regions
// overlap (see `DecorationOrder`).
drop(g);
let g = crate::spans::guard("st_decorate");
let workers = self.threads.len();
if self.decorates && self.order_area != Some((self.center, self.radius)) {
let (decorated, chunks) = (&self.decorated, &world.chunks);
@@ -1546,6 +1559,8 @@ impl Streaming {
self.submit(Some((x, z)), 1, Job::Decorate(x, z, region, finals));
}
}
drop(g);
let g = crate::spans::guard("st_schedule");
self.schedule_generation(world, workers);
// Lighting once all neighbours exist, nearest first and only as
// much of it as the workers can chew. Vanilla's light engine also
@@ -1555,6 +1570,8 @@ impl Streaming {
// grew with the render distance and outlived the columns they
// were queued for (#3629). What stays in `dirty_light` is asked
// for again, from the current centre, as capacity frees.
drop(g);
let g = crate::spans::guard("st_light");
let mut light: Vec<(i64, i32, i32)> = Vec::new();
let mut gone: Vec<(i32, i32)> = Vec::new();
for &(x, z) in world.dirty_light.iter() {
@@ -1567,7 +1584,20 @@ impl Streaming {
for key in gone {
world.dirty_light.remove(&key);
}
drop(g);
let g = crate::spans::guard("st_light_submit");
let room = (self.threads.len() * 4).saturating_sub(self.lighting.len());
if crate::spans::enabled() && self.sequence % 50 == 0 {
log::info!(
"stdbg dirty_light {} ready {} room {} decorated {} protos {} chunks {}",
world.dirty_light.len(),
light.len(),
room,
self.decorated.len(),
self.protos.len(),
world.chunks.len()
);
}
nearest_first(&mut light, room);
for (_, x, z) in light {
let Some(region) = self.light_region(world, x, z) else {
@@ -1584,6 +1614,7 @@ impl Streaming {
Job::Light(x, z, region, self.sequence, self.sky_light),
);
}
drop(g);
// A server draws nothing: its sections are never meshed.
if !self.mesh {
world.dirty_sections.clear();