Skip to content

Commit 8f254f0

Browse files
committed
ref: exclude benchmark harness from measurement via collection steady-state
Toggle callgrind collection off once at process start and make the PauseTiming()/ResumeTiming() toggles unconditional. Collection is now only enabled inside the benchmark loop, so State setup, timer reads and instrument-hooks zero/dump requests no longer appear in the measurement, and the codspeed_in_benchmark_loop_ gating flag is no longer needed. The toggle is inlined via CALLGRIND_TOGGLE_COLLECT directly (instead of calling the instrument-hooks wrapper) so no toggle frame shows up in flamegraphs; the counted boundary shrinks to the ResumeTiming() epilogue (~6 instructions). SkipWithMessage/SkipWithError restore the toggle parity when a benchmark is skipped mid-loop without pausing. Refs COD-2033
1 parent 198b668 commit 8f254f0

3 files changed

Lines changed: 27 additions & 39 deletions

File tree

core/include/measurement.hpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,25 @@ ALWAYS_INLINE void measurement_add_benchmark_timestamps(uint64_t start,
8888
measurement_add_marker(MARKER_TYPE_BENCHMARK_END, end);
8989
}
9090

91+
#ifdef CODSPEED_ANALYSIS
92+
static bool measurement_collecting = true;
93+
94+
ALWAYS_INLINE void measurement_pause_timing() {
95+
if (measurement_collecting) {
96+
callgrind_toggle_collect();
97+
measurement_collecting = false;
98+
}
99+
}
100+
101+
ALWAYS_INLINE void measurement_resume_timing() {
102+
if (!measurement_collecting) {
103+
callgrind_toggle_collect();
104+
measurement_collecting = true;
105+
}
106+
}
107+
#else
108+
ALWAYS_INLINE void measurement_pause_timing() {}
109+
ALWAYS_INLINE void measurement_resume_timing() {}
110+
#endif
111+
91112
#endif // MEASUREMENT_H

google_benchmark/include/benchmark/benchmark.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -949,15 +949,6 @@ class BENCHMARK_EXPORT BENCHMARK_INTERNAL_CACHELINE_ALIGNED State {
949949
#if defined(CODSPEED_ANALYSIS) || defined(CODSPEED_WALLTIME)
950950
codspeed::CodSpeed* codspeed_;
951951
#endif
952-
#ifdef CODSPEED_ANALYSIS
953-
// True between the implicit ResumeTiming() in StartKeepRunning() and the
954-
// implicit PauseTiming() in FinishKeepRunning(). Only explicit user
955-
// PauseTiming()/ResumeTiming() calls (inside the benchmark loop) may
956-
// toggle callgrind collection: CALLGRIND_TOGGLE_COLLECT is parity-based,
957-
// and collection starts enabled, so the implicit bracket calls must not
958-
// toggle or they would invert the collection state for the whole run.
959-
bool codspeed_in_benchmark_loop_;
960-
#endif
961952
#ifdef CODSPEED_WALLTIME
962953
uint64_t resume_timestamp_;
963954
#endif

google_benchmark/src/benchmark.cc

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@
1919
#include "codspeed.h"
2020
#include "internal_macros.h"
2121

22-
#if defined(CODSPEED_WALLTIME) || defined(CODSPEED_ANALYSIS)
2322
#include "measurement.hpp"
24-
#endif
2523

2624
#ifndef BENCHMARK_OS_WINDOWS
2725
#if !defined(BENCHMARK_OS_FUCHSIA) && !defined(BENCHMARK_OS_QURT)
@@ -61,6 +59,8 @@
6159
#include "thread_timer.h"
6260

6361
namespace benchmark {
62+
63+
6464
// Print a list of benchmarks. This option overrides all other options.
6565
BM_DEFINE_bool(benchmark_list_tests, false);
6666

@@ -199,9 +199,6 @@ State::State(std::string name, IterationCount max_iters,
199199
#if defined(CODSPEED_ANALYSIS) || defined(CODSPEED_WALLTIME)
200200
codspeed_(codspeed),
201201
#endif
202-
#ifdef CODSPEED_ANALYSIS
203-
codspeed_in_benchmark_loop_(false),
204-
#endif
205202
#ifdef CODSPEED_WALLTIME
206203
resume_timestamp_(0),
207204
#endif
@@ -275,15 +272,7 @@ void State::PauseTiming() {
275272
#ifdef CODSPEED_WALLTIME
276273
uint64_t pause_timestamp = measurement_current_timestamp();
277274
#endif
278-
#ifdef CODSPEED_ANALYSIS
279-
// Suspend callgrind cost collection for the paused section. Toggling
280-
// collection (unlike stopping instrumentation) does not flush the
281-
// simulated cache, so it adds no artificial cold-cache cost to the
282-
// measured region.
283-
if (codspeed_in_benchmark_loop_) {
284-
callgrind_toggle_collect();
285-
}
286-
#endif
275+
measurement_pause_timing();
287276

288277
// Add in time accumulated so far
289278
BM_CHECK(started_ && !finished_ && !skipped());
@@ -322,12 +311,7 @@ void State::ResumeTiming() {
322311
BM_CHECK(resume_timestamp_ == 0);
323312
resume_timestamp_ = measurement_current_timestamp();
324313
#endif
325-
#ifdef CODSPEED_ANALYSIS
326-
// Re-enable callgrind cost collection after a paused section.
327-
if (codspeed_in_benchmark_loop_) {
328-
callgrind_toggle_collect();
329-
}
330-
#endif
314+
measurement_resume_timing();
331315
}
332316

333317
void State::SkipWithMessage(const std::string& msg) {
@@ -342,6 +326,7 @@ void State::SkipWithMessage(const std::string& msg) {
342326
total_iterations_ = 0;
343327
if (timer_->running()) {
344328
timer_->StopTimer();
329+
measurement_pause_timing();
345330
}
346331
}
347332

@@ -357,6 +342,7 @@ void State::SkipWithError(const std::string& msg) {
357342
total_iterations_ = 0;
358343
if (timer_->running()) {
359344
timer_->StopTimer();
345+
measurement_pause_timing();
360346
}
361347
}
362348

@@ -379,22 +365,12 @@ void State::StartKeepRunning() {
379365
manager_->StartStopBarrier();
380366
if (!skipped()) {
381367
ResumeTiming();
382-
#ifdef CODSPEED_ANALYSIS
383-
// Arm collection toggling only after the implicit ResumeTiming() above,
384-
// so that only explicit user pauses inside the loop toggle collection.
385-
codspeed_in_benchmark_loop_ = true;
386-
#endif
387368
}
388369
}
389370

390371
void State::FinishKeepRunning() {
391372
BM_CHECK(started_ && (!finished_ || skipped()));
392373
if (!skipped()) {
393-
#ifdef CODSPEED_ANALYSIS
394-
// Disarm before the implicit PauseTiming() below so it does not toggle
395-
// collection off for the rest of the process.
396-
codspeed_in_benchmark_loop_ = false;
397-
#endif
398374
PauseTiming();
399375
}
400376
// Total iterations has now wrapped around past 0. Fix this.

0 commit comments

Comments
 (0)