Files
lightcraft/crates/raster/examples/blur_bench.rs
T
Brandon ThomasandClaude Opus 5.5 0892148bab M5.3: faster per-pixel stage and row-parallel guided filter
- finish: sRGB encode through an interpolated 4096-entry table (< 2e-5 from the exact curve,
  tested), exp2 instead of powf(2, x).
- guided / guided_fast: coefficient and output passes run row-parallel (were serial loops);
  Image::zip_map.
- blur_bench reports process CPU time next to wall-clock (meaningful on a loaded machine).
- RENDER_CACHE_VERSION 3 (exposure-after-filters and the table change pixels by <= 2 LSB).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 00:57:02 -04:00

43 lines
1.6 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! Micro-benchmark for the blur/map primitives (min of N runs, wall-clock and process CPU time, so
//! it stays meaningful on a loaded machine):
//! `RAYON_NUM_THREADS=1 cargo run --release -p lightcraft-raster --example blur_bench`.
use lightcraft_raster::{Plane, Rgb32f, blur::gaussian};
use std::time::Instant;
/// Process CPU time in ms (all threads). The only `unsafe` is this libc clock read, in a dev-only example.
#[allow(unsafe_code)]
fn cpu_ms() -> f64 {
#[cfg(unix)]
{
let mut ts = libc::timespec { tv_sec: 0, tv_nsec: 0 };
// SAFETY: `clock_gettime` only writes into the timespec we pass.
unsafe { libc::clock_gettime(libc::CLOCK_PROCESS_CPUTIME_ID, &mut ts) };
ts.tv_sec as f64 * 1e3 + ts.tv_nsec as f64 / 1e6
}
#[cfg(not(unix))]
{
0.0
}
}
fn best(n: usize, mut f: impl FnMut()) -> String {
let (mut wall, mut cpu) = (f64::MAX, f64::MAX);
for _ in 0..n {
let (t, c) = (Instant::now(), cpu_ms());
f();
cpu = cpu.min(cpu_ms() - c);
wall = wall.min(t.elapsed().as_secs_f64() * 1e3);
}
format!("{wall:.1} ms wall, {cpu:.1} ms cpu")
}
fn main() {
let (w, h) = (3000, 2400);
let p = Plane::from_fn(w, h, |x, y| ((x * 7 + y * 13) % 255) as f32 / 255.0);
let c = Rgb32f::from_fn(w, h, |x, y| [x as f32 / w as f32, y as f32 / h as f32, 0.5]);
for sigma in [1.0f32, 4.0, 24.0] {
println!("plane gaussian σ={sigma}: {}", best(9, || drop(gaussian(&p, sigma))));
}
println!("rgb gaussian σ=4: {}", best(9, || drop(gaussian(&c, 4.0))));
}