![]() |
OpenSWMM Engine
6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
|
Classes | |
| class | CounterBatch |
| Private counters for one worker in a worksharing phase. Nested batches merge into the enclosing worker's batch. The outer batch merges under one lock after the loop; hydraulic arithmetic is unaffected. When profiling is disabled, no counters are initialized or merged. More... | |
| struct | GatedTimer |
| struct | ProcessPhaseName |
| class | ProcessTimer |
| struct | ScopedTimer |
| struct | SigmaEvaluations |
Typedefs | |
| using | FvCounts = std::array<long, n_fv_counter_count> |
| using | AllocationSnapshot = void (*)(std::uint64_t*, std::uint64_t*) |
Functions | |
| long | value (FvCounter counter) noexcept |
| Read one process-global completed FV counter total. | |
| void | reset_fv () noexcept |
| Zero FV phase timers and completed counter totals. | |
| void | dump_fv () noexcept |
| One machine-scrapeable line for the FV phase split. | |
| std::chrono::steady_clock::time_point | now () noexcept |
| Sample the steady monotonic clock regardless of profiling enablement. | |
| double | since (std::chrono::steady_clock::time_point t0) noexcept |
| Measure elapsed wall time from a steady-clock sample. | |
| bool | enabled () noexcept |
| Read the process-cached profiling environment gate. | |
| void | reset_load () noexcept |
| Zero load/open/initialize/start phase accumulators. | |
| void | dump_load () noexcept |
| One machine-scrapeable line per phase on stderr. | |
| void | count (FvCounter counter, long n=1) noexcept |
| Accumulate a batch of events into worker-private or serial global counters. | |
| AllocationSnapshot | allocation_snapshot () noexcept |
| void | count (ProcessCounter counter, unsigned long long n=1) noexcept |
| unsigned long long | value (ProcessCounter counter) noexcept |
| void | clear_process_totals () noexcept |
| void | reset_process () noexcept |
| void | begin_process_model (const void *model) noexcept |
| void | dump_process () noexcept |
| void | end_process_model (const void *model, bool report=true) noexcept |
Variables | |
| double | sec_2d_window = 0.0 |
| double | sec_2d_advance = 0.0 |
| double | sec_1d_step = 0.0 |
| double | sec_open_prescan2d = 0.0 |
| double | sec_open_read = 0.0 |
| double | sec_read_dispatch = 0.0 |
| double | sec_open_resolve = 0.0 |
| double | sec_open_validate = 0.0 |
| double | sec_res_extfiles = 0.0 |
| double | sec_res_tables = 0.0 |
| double | sec_res_transects = 0.0 |
| double | sec_res_xsect = 0.0 |
| double | sec_res_shrink = 0.0 |
| double | sec_init_state = 0.0 |
| double | sec_init_hydraulics = 0.0 |
| double | sec_init_hydrology = 0.0 |
| double | sec_init_quality = 0.0 |
| double | sec_init_geometry = 0.0 |
| double | sec_start_iface = 0.0 |
| double | sec_start_plugins = 0.0 |
| double | sec_fv_census = 0.0 |
| double | sec_fv_flux = 0.0 |
| double | sec_fv_nodesolve = 0.0 |
| double | sec_fv_positivity = 0.0 |
| double | sec_fv_cellupdate = 0.0 |
| double | sec_fv_nodeupdate = 0.0 |
| double | sec_fv_refreshdep = 0.0 |
| double | sec_fv_savestate = 0.0 |
| double | sec_fv_restore = 0.0 |
| double | sec_fv_structref = 0.0 |
| double | sec_fv_bndcallback = 0.0 |
| double | sec_fv_rebuild = 0.0 |
| double | sec_fv_reconstruct = 0.0 |
| double | sec_fv_ltsfire = 0.0 |
| double | sec_fv_settle = 0.0 |
| double | sec_fv_tier = 0.0 |
| FvCounts | fv_counts {} |
| thread_local FvCounts * | local_fv_counts = nullptr |
| std::mutex | fv_counts_mutex |
| thread_local double | nested_wall = 0.0 |
| ScopedTimer that reads the clock only when OPENSWMM_PERF is set. | |
| constexpr std::array< ProcessPhaseName, std::size_t(ProcessPhase::count)> | process_names |
| std::array< std::atomic< double >, std::size_t(ProcessPhase::count)> | process_seconds {} |
| std::array< std::atomic< unsigned long long >, std::size_t(ProcessPhase::count)> | process_calls {} |
| std::array< std::atomic< unsigned long long >, std::size_t(ProcessPhase::count)> | process_allocations {} |
| std::array< std::atomic< unsigned long long >, std::size_t(ProcessPhase::count)> | process_allocated_bytes {} |
| std::atomic< bool > | process_attribution_valid {true} |
| std::mutex | process_models_mutex |
| std::unordered_set< const void * > | process_models |
| bool | process_tracking_failed = false |
| constexpr std::array< const char *, std::size_t(ProcessCounter::count)> | process_counter_names |
| std::array< std::atomic< unsigned long long >, std::size_t(ProcessCounter::count)> | process_counts {} |
| using openswmm::perf::AllocationSnapshot = void (*)(std::uint64_t*, std::uint64_t*) |
| using openswmm::perf::FvCounts = std::array<long, n_fv_counter_count> |
| enum openswmm::perf::FvCounter : std::size_t |
|
strong |
|
strong |
|
inlinenoexcept |
|
inlinenoexcept |
|
inlinenoexcept |
|
inlinenoexcept |
Accumulate a batch of events into worker-private or serial global counters.
No-op when profiling is disabled. Parallel callers must install a CounterBatch; without one updates global fv_counts without a lock.
| [in] | counter | Valid FvCounter below n_fv_counter_count; no bounds check. |
| [in] | n | Increment, default one; may be zero/negative. Caller prevents signed-long overflow. |
|
inlinenoexcept |
|
inlinenoexcept |
One machine-scrapeable line for the FV phase split.
Same [PERF-FV] key=value contract as dump_load(); emitted from close() when OPENSWMM_PERF is set and the FV solver actually ran. Each phase is SELF time: a phase that calls another timed phase is charged only for its own work (see nested_wall), so the phases partition the time rather than overlapping it. total is their sum, NOT the router step — the difference between the two is unattributed time and is itself the useful signal when a phase is missing. It cannot be negative; if it ever is, a timer is nested inside a scope that does not go through GatedTimer.
|
inlinenoexcept |
One machine-scrapeable line per phase on stderr.
Emitted from close() so all three benchmark cuts (open only, open+initialize, full) report. Format is [PERF-LOAD] key=value pairs in seconds; tests/benchmarks/scripts/ parses it.
|
inlinenoexcept |
|
inlinenoexcept |
Read the process-cached profiling environment gate.
Subsequent environment changes are ignored. C++ function-local static initialization is thread-safe.
|
inlinenoexcept |
|
inlinenoexcept |
Sample the steady monotonic clock regardless of profiling enablement.
|
inlinenoexcept |
Zero FV phase timers and completed counter totals.
Does not reset sec_1d_step or active thread-local batches. Caller invokes only between worksharing regions with no concurrent counter/timer use.
|
inlinenoexcept |
Zero load/open/initialize/start phase accumulators.
Does not reset runtime FV/1D/2D totals or environment gate; caller serializes reset with timer updates.
|
inlinenoexcept |
|
inlinenoexcept |
Measure elapsed wall time from a steady-clock sample.
| [in] | t0 | Earlier steady-clock time point; a future value yields a negative duration. |
|
inlinenoexcept |
Read one process-global completed FV counter total.
Read only between worksharing regions or under external synchronization.
| [in] | counter | Valid FvCounter below n_fv_counter_count; no bounds check. |
|
inlinenoexcept |
|
inline |
|
inline |
|
inline |
|
inline |
ScopedTimer that reads the clock only when OPENSWMM_PERF is set.
ScopedTimer is used at per-routing-step and per-load-phase call sites, where two unconditional clock reads are free. The FV phase timers are not in that regime: a 30 h / 5 s run is ~21,600 routing steps, each of which can carry hundreds of substeps, each carrying a dozen phases. At ~20 ns a read that is seconds of pure instrument on a run that has nothing to do with profiling. enabled() is a cached static bool, so the gated form costs a predicted branch instead. Wall time booked by GatedTimers that opened and closed inside the one currently running on this thread. Read and reset by each timer so that what lands in the accumulator is SELF time.
Without this the phase split double-counts wherever one timed phase calls another, which it does in three places today: restoreState and settleAccumulators both call refreshDepths, and runMacroCycle's boundary callback sits inside the settle window. The visible symptom was total exceeding the routing step it is a breakdown of — the LTS rows of the phase table reported between -7.9 % and -18.1 % "unattributed" time, which is not a quantity that can be negative. A breakdown whose parts can exceed the whole cannot rank optimization targets, which is the only reason these timers exist.
Thread-local because the accumulators are serial-path today but the flux sweep is slated to go parallel; a shared counter would then attribute one thread's children to another thread's parent. Nothing here is atomic and nothing needs to be: a timer only ever touches its own thread's tally.
|
inline |
|
inline |
|
inline |
|
inline |
|
inlineconstexpr |
|
inline |
|
inline |
|
inline |
|
inlineconstexpr |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |