fix: a paused view carries its own LOD pyramid, so it is drawn like a held event
publish_pause_view() filled stamps, values and y and left pyramids empty, so level_for() descended to raw samples and a frozen pause was re-gathered from every sample it held on every frame. It cost draw time (12.34 -> 18.18 ms mean) and, because stage_trace_density() normalises each column against its own peak, it also changed how the trace looked -- which is how it was noticed. Both publishes are now timed and reported as `publish cost:`, counted apart because they stall opposite threads: the event publish runs on the producer under mutex() and blocks the UI, the pause publish runs on the UI thread and blocks the producer. That is the number a second live ring has to be judged against. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
13574bfcef
commit
d2c51f2448
5 files changed
+175
-4
No files matched your search
+22
@@ -8383,6 +8383,28 @@ int run_ui(int argc, char** argv, const Config& cfg, ScopeModel& model, Acquisit
|
||||
per_slot * static_cast<double>(app.model->math_slots()) / 1.0e6);
|
||||
}
|
||||
}
|
||||
// What freezing a view costs, counted apart for the two publishes because they stall opposite
|
||||
// threads (see `ScopeModel::publish_event_count()`). This is the figure a second live ring would
|
||||
// buy: freezing a whole `BufferStore` copies nothing and inherits the pyramid the producer
|
||||
// already maintains, so both `worst` figures would be 0 -- at a second budget's worth of memory
|
||||
// and a second per-sample write on the producer. Read `event worst` against `frame cost:`'s
|
||||
// `tick` max (the same stall, seen from the UI) and `pause worst` against `gaps`.
|
||||
{
|
||||
const auto ev = app.model->publish_event_count();
|
||||
const auto pa = app.model->publish_pause_count();
|
||||
std::printf("[udpscope] publish cost: %llu events, %.2f/%.2f ms (mean/worst, blocks the UI);"
|
||||
" %llu pauses, %.2f/%.2f ms (mean/worst, blocks the producer)\n",
|
||||
static_cast<unsigned long long>(ev),
|
||||
ev > 0 ? static_cast<double>(app.model->publish_event_us_total()) /
|
||||
static_cast<double>(ev) / 1000.0
|
||||
: 0.0,
|
||||
static_cast<double>(app.model->publish_event_us_worst()) / 1000.0,
|
||||
static_cast<unsigned long long>(pa),
|
||||
pa > 0 ? static_cast<double>(app.model->publish_pause_us_total()) /
|
||||
static_cast<double>(pa) / 1000.0
|
||||
: 0.0,
|
||||
static_cast<double>(app.model->publish_pause_us_worst()) / 1000.0);
|
||||
}
|
||||
// Unconditional, unlike the pane's own lines below: this is about the instruments the app
|
||||
// *created*, which exist whether or not any measurement was added.
|
||||
std::printf("[udpscope] readout instruments locked: %d (trigger marker + measurement marks)\n",
|
||||
|
||||
Reference in new issue
Block a user