|
1 | 1 | # Marching cubes performance |
2 | 2 |
|
| 3 | +## Codex-Sol / Claude consolidation (2026-07-11) |
| 4 | + |
| 5 | +The consolidation pass kept the Codex-Sol float32 MC33 kernel, exact |
| 6 | +scikit-image normal/value semantics, and zero-copy NumPy handoff. It moved |
| 7 | +axis conversion and winding into triangle emission, added robust transitive |
| 8 | +degenerate-vertex merging with the shared `UnionFind`, and broadened the |
| 9 | +correctness and benchmark suites. Scalar spacing is now accepted as an |
| 10 | +isotropic convenience. |
| 11 | + |
| 12 | +The benchmark now has a backward-compatible single-size mode and a full |
| 13 | +scaling suite matching the independent implementation comparison: |
| 14 | + |
| 15 | +```bash |
| 16 | +python development/mesh/benchmark_marching_cubes.py --size medium |
| 17 | +python development/mesh/benchmark_marching_cubes.py \ |
| 18 | + --suite scaling --repeats 5 --batches 1 --warmup 1 --memory \ |
| 19 | + --json /tmp/marching-cubes.json |
| 20 | +``` |
| 21 | + |
| 22 | +The scaling suite alternates paired bioimage-cpp/scikit-image calls and covers |
| 23 | +Lewiner spheres/scalar fields through 512³, dense 10%-foreground masks through |
| 24 | +256³, and all three Lorensen workloads at 128³. Fresh subprocesses measure |
| 25 | +peak RSS before the timing process allocates any large volumes. |
| 26 | + |
| 27 | +Same-harness before/after results on the machine described below: |
| 28 | + |
| 29 | +| case | before ms | after ms | change | scikit-image / after | |
| 30 | +|---|---:|---:|---:|---:| |
| 31 | +| sphere, Lewiner, 512³ | 1,898.68 | 1,786.24 | -5.9% | 1.06× | |
| 32 | +| dense mask, Lewiner, 256³ | 2,119.26 | 2,063.38 | -2.6% | 1.98× | |
| 33 | +| scalar field, Lewiner, 512³ | 2,268.58 | 2,295.50 | +1.2% | 1.30× | |
| 34 | +| sphere, Lorensen, 128³ | 30.31 | 28.39 | -6.3% | 1.31× | |
| 35 | +| dense mask, Lorensen, 128³ | 192.19 | 212.75 | +10.7% | 2.16× | |
| 36 | +| scalar field, Lorensen, 128³ | 48.72 | 49.80 | +2.2% | 1.84× | |
| 37 | + |
| 38 | +Absolute timings moved with CPU state: across all 15 cases the geometric-mean |
| 39 | +wall time improved 2.4%, while normalization by each paired scikit-image time |
| 40 | +showed a 1.1% improvement. Targeted same-session A/B repeats against the exact |
| 41 | +pre-change commit resolved the apparent small-scalar and dense-Lorensen |
| 42 | +regressions: scalar 64³ retained a ~2.04–2.06× paired speedup, while dense |
| 43 | +Lorensen improved from ~2.01–2.02× to ~2.08×. No reproducible regression above |
| 44 | +3% remained. |
| 45 | + |
| 46 | +Peak RSS was unchanged within measurement noise: |
| 47 | + |
| 48 | +| case | before MiB | after MiB | scikit-image MiB | |
| 49 | +|---|---:|---:|---:| |
| 50 | +| sphere 512³ | 725.8 | 725.7 | 734.6 | |
| 51 | +| dense mask 256³ | 643.5 | 643.5 | 1,108.6 | |
| 52 | +| scalar field 512³ | 703.3 | 703.4 | 843.3 | |
| 53 | + |
| 54 | +Correctness validation finished with 29 mesh tests, 1,024 full-suite tests, |
| 55 | +all 254 nontrivial binary cube configurations for both methods, 1,024 random |
| 56 | +scalar cubes for both methods, and 1,000 randomized multi-cube mask/stride/ |
| 57 | +degeneracy cases. Twelve `allow_degenerate=False` cases intentionally differed |
| 58 | +from scikit-image's negative-index remapping quirk; all returned faces were |
| 59 | +valid and contained no collapsed-coordinate triangles. |
| 60 | + |
| 61 | +## Two-slice face-cache optimization |
| 62 | + |
3 | 63 | `bic.mesh.marching_cubes` remains deterministic and single-threaded. The |
4 | 64 | optimization pass replaced the volume-growing edge hash map with Lewiner's |
5 | 65 | two-slice face cache. Several smaller candidates were measured first and |
|
0 commit comments