![]() |
OpenSWMM Engine
6.0.0-alpha.4
Data-oriented, plugin-extensible SWMM Engine (6.0.0-alpha.4)
|
Classes | |
| struct | GatedTimer |
| struct | ScopedTimer |
Functions | |
| void | reset_fv () noexcept |
| Zeroes the FV phase accumulators. Called from Router::initFv. | |
| void | dump_fv () noexcept |
| One machine-scrapeable line for the FV phase split. | |
| std::chrono::steady_clock::time_point | now () noexcept |
| Manual timing pair, for phases that do not fit a lexical scope. | |
| double | since (std::chrono::steady_clock::time_point t0) noexcept |
| bool | enabled () noexcept |
| True when OPENSWMM_PERF is set. Cached — getenv is not free. | |
| void | reset_load () noexcept |
| Zeroes the load-phase accumulators. Called from open(). | |
| void | dump_load () noexcept |
| One machine-scrapeable line per phase on stderr. | |
| void | count (long &c, long n=1) noexcept |
|
inlinenoexcept |
Adds n to a counter only when profiling is on, so the counters cost the same predicted branch as the timers and never appear in a release profile.
|
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 |
True when OPENSWMM_PERF is set. Cached — getenv is not free.
|
inlinenoexcept |
Manual timing pair, for phases that do not fit a lexical scope.
|
inlinenoexcept |
Zeroes the FV phase accumulators. Called from Router::initFv.
|
inlinenoexcept |
Zeroes the load-phase accumulators. Called from open().
|
inlinenoexcept |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
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 |
|
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 |