mirror of
https://github.com/esphome/esphome.git
synced 2026-09-17 18:18:43 +00:00
Fix scheduler firing benchmark: no inner loop, warm-up call
- Revert component.h change (no core changes for benchmarks) - Remove -DWARN_IF_BLOCKING_OVER_MS from build flags (can't shadow constexpr) - Drop inner loop — 5 heap pops + callbacks + pushes per call is well above CodSpeed's 60ns instrumentation overhead - Add warm-up call before benchmark loop to trigger the blocking guard once and ramp the threshold - interval=0 causes infinite loop, must use interval=1 with fake time
This commit is contained in:
@@ -34,10 +34,6 @@ PLATFORMIO_OPTIONS = {
|
||||
"-O2", # optimize for speed (CodSpeed recommends RelWithDebInfo)
|
||||
"-g", # debug symbols for profiling
|
||||
USE_TIME_TIMEZONE_FLAG,
|
||||
# Disable WarnIfComponentBlockingGuard check — scheduler benchmarks
|
||||
# use fake monotonic time ahead of real millis(), causing uint32_t
|
||||
# underflow in the guard's (millis() - started_) calculation.
|
||||
"-DWARN_IF_BLOCKING_OVER_MS=UINT32_MAX",
|
||||
],
|
||||
# Use deep+ LDF mode to ensure PlatformIO detects the benchmark
|
||||
# library dependency from nested includes.
|
||||
|
||||
@@ -67,25 +67,27 @@ static void Scheduler_Call_5IntervalsFiring(benchmark::State &state) {
|
||||
int fire_count = 0;
|
||||
|
||||
// Add 5 intervals with 1ms period — they fire every call when time advances.
|
||||
// We use monotonically increasing fake time (now++) so intervals reliably fire.
|
||||
// WARN_IF_BLOCKING_OVER_MS=UINT32_MAX in benchmark build flags prevents the
|
||||
// WarnIfComponentBlockingGuard from triggering when fake time exceeds real millis().
|
||||
// Note: interval=0 causes an infinite loop (reschedules at same time, never breaks).
|
||||
// No inner loop needed: 5 heap pops + 5 callbacks + 5 heap pushes per call
|
||||
// is well above CodSpeed's ~60ns instrumentation overhead.
|
||||
// Note: interval=0 causes infinite loop (reschedules at same now, never breaks).
|
||||
for (int i = 0; i < 5; i++) {
|
||||
scheduler.set_interval(&dummy_component, static_cast<uint32_t>(i), 1, [&fire_count]() { fire_count++; });
|
||||
}
|
||||
scheduler.process_to_add();
|
||||
|
||||
// Monotonically increasing fake time so intervals are due every call.
|
||||
// Can't use real millis() — it doesn't advance fast enough between calls.
|
||||
// Warm-up call outside the benchmark to trigger the blocking guard once
|
||||
// and ramp the component's warn_if_blocking_over_ threshold to max.
|
||||
uint32_t now = millis() + 100;
|
||||
scheduler.call(now);
|
||||
now++;
|
||||
|
||||
for (auto _ : state) {
|
||||
for (int i = 0; i < kInnerIterations; i++) {
|
||||
scheduler.call(now);
|
||||
now++;
|
||||
}
|
||||
scheduler.call(now);
|
||||
now++;
|
||||
benchmark::DoNotOptimize(fire_count);
|
||||
}
|
||||
state.SetItemsProcessed(state.iterations() * kInnerIterations);
|
||||
}
|
||||
BENCHMARK(Scheduler_Call_5IntervalsFiring);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user