diff --git a/script/cpp_benchmark.py b/script/cpp_benchmark.py index 17613c2842..f30054fbad 100755 --- a/script/cpp_benchmark.py +++ b/script/cpp_benchmark.py @@ -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. diff --git a/tests/benchmarks/core/bench_scheduler.cpp b/tests/benchmarks/core/bench_scheduler.cpp index 4e3ef57084..1b78c44376 100644 --- a/tests/benchmarks/core/bench_scheduler.cpp +++ b/tests/benchmarks/core/bench_scheduler.cpp @@ -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(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);