diff --git a/benches/plot.py b/benches/plot.py index 03a8969..f972c28 100644 --- a/benches/plot.py +++ b/benches/plot.py @@ -9,21 +9,20 @@ # benchmark 1..=10^max rays/triangles max = 4 -#newcmp = LinearSegmentedColormap('testCmap', segmentdata=cdict, N=256) cmap = LinearSegmentedColormap.from_list("speedup", ["red", "white", "green"], N=256) def plot(colormaps): mesh = [] - for x in range(1 * resolution, max * resolution + 1): + for x in range(0, max * resolution + 1): mesh.append(round(math.pow(10, x * (1.0 / resolution)))) - data = np.empty(((max - 1) * resolution + 1, (max - 1) * resolution + 1)) + data = np.empty((max * resolution + 1, max * resolution + 1)) with np.nditer(data, flags=['multi_index'], op_flags=['writeonly']) as it: for x in it: rays = mesh[it.multi_index[0]] triangles = mesh[it.multi_index[1]] - samples = 11 + samples = 51 if triangles >= 100 and rays >= 100: # these run longer so less intrinsic noise; save time # by sampling less @@ -57,4 +56,4 @@ def plot(colormaps): fig.colorbar(psm, ax=ax) plt.show() -plot([None]) \ No newline at end of file +plot([None]) diff --git a/benches/src/main.rs b/benches/src/main.rs index a07cef0..f269fe8 100644 --- a/benches/src/main.rs +++ b/benches/src/main.rs @@ -26,10 +26,12 @@ fn main() { let mut rng = rng(); let mut samples = Vec::new(); + let mut rays = Vec::new(); + let mut triangles = Vec::new(); - for _ in 0..cli.samples { - let mut rays = Vec::new(); - let mut triangles = Vec::new(); + for i in 0..cli.samples { + rays.clear(); + triangles.clear(); for _ in 0..cli.rays { rays.push(Ray::::new( @@ -79,27 +81,44 @@ fn main() { }); } - let start_brute_force = Instant::now(); - for ray in &rays { - black_box( - black_box(&triangles) - .iter() - .filter(|triangle| triangle.intersect(&ray)) - .count(), - ); - } - let brute_force_duration = start_brute_force.elapsed().as_secs_f64(); - - let start_bvh = Instant::now(); - let bvh = Bvh::build(&mut triangles); - for ray in &rays { - black_box( - bvh.traverse_iterator(black_box(ray), black_box(&triangles)) - .filter(|triangle| triangle.intersect(&ray)) - .count(), - ); + let mut brute_force_duration = f64::NAN; + let mut bvh_duration = f64::NAN; + + let mut measure_brute_force = |triangles: &[Triangle]| { + let start_brute_force = Instant::now(); + for ray in &rays { + black_box( + black_box(&triangles) + .iter() + .filter(|triangle| triangle.intersect(&ray)) + .count(), + ); + } + brute_force_duration = start_brute_force.elapsed().as_secs_f64(); + }; + + let mut measure_bvh = |triangles: &mut Vec| { + let start_bvh = Instant::now(); + let bvh = Bvh::build(black_box(triangles)); + for ray in &rays { + black_box( + bvh.traverse_iterator(black_box(ray), black_box(&triangles)) + .filter(|triangle| triangle.intersect(&ray)) + .count(), + ); + } + bvh_duration = start_bvh.elapsed().as_secs_f64(); + }; + + // Flip order to minimize bias due to caching. + if i % 2 == 0 { + measure_bvh(&mut triangles); + measure_brute_force(&triangles); + } else { + measure_brute_force(&triangles); + measure_bvh(&mut triangles); } - let bvh_duration = start_bvh.elapsed().as_secs_f64(); + let bvh_speedup = brute_force_duration / bvh_duration; samples.push(bvh_speedup); }