Files
FluidSimCpp/verification/V8_PIPE_PERFORMANCE.md
2026-10-23 18:29:51 +02:00

78 lines
3.4 KiB
Markdown

# V8 pipe resolution and performance check
Measured on an Intel Core i5-12600K with GCC 16.2.1, Release (`-O3`, no
fast-math). Each scenario run advances 44,100 frames in pedal mode. Uniform
resolution runs rebuild every V8 pipe to the requested cells/m; cell counts are
rounded up to whole cells, so short pipes can be slightly denser than the target.
## Resolution sweep
| Requested cells/m | Wall time per simulated second | Solver substeps/frame |
|---:|---:|---:|
| Existing per-pipe meshes | 0.429 s | 1.00 |
| 20 | 0.421 s | 1.00 |
| 30 | 0.793 s | 1.53 |
| 33 | 0.886 s | 1.74 |
| 35 | 0.979 s | 1.80 |
| 36 | 1.048 s | 1.82 |
| 40 | 1.151 s | 1.89 |
Thirty-five cells/m was barely faster than real time on this host; 36 missed
real time. The existing per-pipe mesh is substantially faster and remains the
default.
These are one-second runs at one workload and machine; they do not establish a
cross-machine guarantee.
A second sweep held the V8 at 4,500 RPM (`loaded` mode), a steadier workload:
| Requested cells/m | Wall time per simulated second |
|---:|---:|
| Existing per-pipe meshes | 0.424 s |
| 25 | 0.552 s |
| 30 | 0.830 s |
| 32 | 0.951 s |
| 33 | 0.983 s |
| 34 | 1.049 s |
Thirty-three cells/m only just stayed under real time, while 34 missed. For
headroom, 25 cells/m took 0.55 s and 30 cells/m took 0.83 s; the existing
per-pipe setting remains much faster.
Run with `fluidsim_scenario_benchmark 1 pedal v8 <cells-per-meter>`. The optional
last argument affects only this benchmark's V8 instance and does not change
application mesh defaults.
## Pipe threading
The isolated pipe-advance benchmark used the same 35 cells/m V8 mesh and 4,000
steps. It measured 31.6 ms with one worker, 28.2 ms with two, and 23.4 ms with
four. This is a 26% reduction in pipe-only time at four workers. Boundary
resolution, engine components, and audio remain serial, and the measured gain
does not include the extra synchronization needed to parallelize both pipe
preparation and advancement in the full solver. Other small scenarios generally
lost with worker threads. No threaded solver path was retained.
Run with `fluidsim_thread_benchmark 35` to include the V8 mesh. Omitting the
argument uses the original per-pipe V8 geometry.
## SIMD and allocations
At 30 cells/m, a five-second V8 run averaged 0.646 s per simulated second with
compiler vectorization enabled and 0.585 s with GCC vectorization disabled,
excluding the first second from each average. State checksums and substep counts
matched. This V8 result did not show a SIMD benefit; the project's existing
optimization audit found SIMD useful for its other scenarios, so the global
setting was left unchanged. A `-march=native` build did not improve the 33
cells/m run (0.891 s versus 0.886 s portable).
Pipe cell, face, state, wave, and next-state vectors are allocated when a pipe
is constructed. `Pipe1D::advance` reuses those buffers and swaps the cell
buffers; it performs no heap allocation per solver substep. Boundaries and
component updates also use their setup-time storage. The desktop snapshot path
does copy pipe geometry and states into fresh vectors each render frame; that is
outside the audio sample update, but could be changed to reuse a persistent
snapshot if UI allocation traffic becomes measurable.
An experiment that precomputed per-cell inverse volumes and area-gradient
factors did not improve the V8 benchmark and was reverted.