Skip to content

Commit 2c22dc5

Browse files
feat(google_benchmark): only run benchmark once in instrumentation mode
1 parent 42d797a commit 2c22dc5

File tree

7 files changed

+82
-6
lines changed

7 files changed

+82
-6
lines changed

google_benchmark/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ option(BENCHMARK_ENABLE_ASSEMBLY_TESTS "Enable building and running the assembly
9797
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
9898
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
9999

100+
# Codspeed specific configuration
101+
include(Codspeed)
100102

101103
# Read the git tags to determine the project version
102104
include(GetGitVersion)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Step 1: Check if CODSPEED_MODE is set via the command line
2+
3+
# CMake cache kind of breaks this mechanism, keeping it for first time
4+
# defaulting
5+
if(NOT DEFINED CODSPEED_MODE)
6+
# Step 2: Check the environment variable CODSPEED_MODE
7+
if(DEFINED $ENV{CODSPEED_RUNNER_MODE})
8+
set(CODSPEED_MODE $ENV{CODSPEED_RUNNER_MODE} FORCE)
9+
else()
10+
# Step 3: Default to "instrumentation" if no value is provided
11+
set(CODSPEED_MODE "instrumentation")
12+
endif()
13+
endif()
14+
15+
# Define a preprocessor macro based on the build mode
16+
if(CODSPEED_MODE STREQUAL "instrumentation")
17+
target_compile_definitions(codspeed INTERFACE -DCODSPEED_INSTRUMENTATION)
18+
elseif(CODSPEED_MODE STREQUAL "walltime")
19+
target_compile_definitions(codspeed INTERFACE -DCODSPEED_WALLTIME)
20+
else()
21+
message(
22+
FATAL_ERROR
23+
"Invalid build mode: ${CODSPEED_MODE}. Use 'instrumentation' or 'walltime'."
24+
)
25+
endif()
26+
27+
message(STATUS "Build mode set to: ${CODSPEED_MODE}")

google_benchmark/src/CMakeLists.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,8 @@ set_target_properties(benchmark_main PROPERTIES
8282
)
8383
target_link_libraries(benchmark_main PUBLIC benchmark::benchmark)
8484

85-
add_subdirectory(${PROJECT_SOURCE_DIR}/../core codspeed)
86-
87-
target_link_libraries(benchmark PRIVATE codspeed)
85+
# TODO: Find a way to not expose codspeed headers to downstream users
86+
target_link_libraries(benchmark PUBLIC codspeed)
8887

8988
set(generated_dir "${PROJECT_BINARY_DIR}")
9089

google_benchmark/src/benchmark.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,9 +382,13 @@ void RunBenchmarks(const std::vector<BenchmarkInstance>& benchmarks,
382382
// Note the file_reporter can be null.
383383
BM_CHECK(display_reporter != nullptr);
384384

385-
hello_codspeed();
386-
387385
// Determine the width of the name field using a minimum width of 10.
386+
#ifdef CODSPEED_INSTRUMENTATION
387+
std::cout << "Codspeed mode: instrumentation" << "\n";
388+
#elif defined(CODSPEED_WALLTIME)
389+
std::cout << "Codspeed mode walltime" << "\n";
390+
#endif
391+
388392
bool might_have_aggregates = FLAGS_benchmark_repetitions > 1;
389393
size_t name_field_width = 10;
390394
size_t stat_field_width = 0;

google_benchmark/src/benchmark_api_internal.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <cinttypes>
44

5+
#include "codspeed.h"
56
#include "string_util.h"
67

78
namespace benchmark {
@@ -89,6 +90,21 @@ BenchmarkInstance::BenchmarkInstance(Benchmark* benchmark, int family_idx,
8990
teardown_ = benchmark_.teardown_;
9091
}
9192

93+
#ifdef CODSPEED_INSTRUMENTATION
94+
State BenchmarkInstance::RunInstrumented(
95+
CodSpeed* codspeed, internal::ThreadTimer* timer,
96+
internal::ThreadManager* manager,
97+
internal::PerfCountersMeasurement* perf_counters_measurement,
98+
ProfilerManager* profiler_manager) const {
99+
State st(name_.function_name, 1, args_, 0, 1, timer, manager,
100+
perf_counters_measurement, profiler_manager);
101+
codspeed->start_benchmark(name().str());
102+
benchmark_.Run(st);
103+
codspeed->end_benchmark();
104+
return st;
105+
}
106+
#endif
107+
92108
State BenchmarkInstance::Run(
93109
IterationCount iters, int thread_id, internal::ThreadTimer* timer,
94110
internal::ThreadManager* manager,

google_benchmark/src/benchmark_api_internal.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
#include <vector>
1010

1111
#include "benchmark/benchmark.h"
12+
#ifdef CODSPEED_INSTRUMENTATION
13+
#include "codspeed.h"
14+
#endif
1215
#include "commandlineflags.h"
1316

1417
namespace benchmark {
@@ -34,7 +37,13 @@ class BenchmarkInstance {
3437
BigO complexity() const { return complexity_; }
3538
BigOFunc* complexity_lambda() const { return complexity_lambda_; }
3639
const std::vector<Statistics>& statistics() const { return statistics_; }
37-
int repetitions() const { return repetitions_; }
40+
int repetitions() const {
41+
#ifdef CODSPEED_INSTRUMENTATION
42+
return 1;
43+
#else
44+
return repetitions_;
45+
#endif
46+
}
3847
double min_time() const { return min_time_; }
3948
double min_warmup_time() const { return min_warmup_time_; }
4049
IterationCount iterations() const { return iterations_; }
@@ -47,6 +56,14 @@ class BenchmarkInstance {
4756
internal::PerfCountersMeasurement* perf_counters_measurement,
4857
ProfilerManager* profiler_manager) const;
4958

59+
#ifdef CODSPEED_INSTRUMENTATION
60+
State RunInstrumented(
61+
CodSpeed* codspeed, internal::ThreadTimer* timer,
62+
internal::ThreadManager* manager,
63+
internal::PerfCountersMeasurement* perf_counters_measurement,
64+
ProfilerManager* profiler_manager) const;
65+
#endif
66+
5067
private:
5168
BenchmarkName name_;
5269
Benchmark& benchmark_;

google_benchmark/src/benchmark_runner.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include <utility>
4343

4444
#include "check.h"
45+
#include "codspeed.h"
4546
#include "colorprint.h"
4647
#include "commandlineflags.h"
4748
#include "complexity.h"
@@ -464,6 +465,16 @@ void BenchmarkRunner::DoOneRepetition() {
464465

465466
const bool is_the_first_repetition = num_repetitions_done == 0;
466467

468+
#ifdef CODSPEED_INSTRUMENTATION
469+
std::unique_ptr<internal::ThreadManager> manager;
470+
manager.reset(new internal::ThreadManager(b.threads()));
471+
internal::ThreadTimer timer = internal::ThreadTimer::Create();
472+
State st = b.RunInstrumented(CodSpeed::getInstance(), &timer, manager.get(),
473+
nullptr, nullptr);
474+
475+
return;
476+
#endif
477+
467478
// In case a warmup phase is requested by the benchmark, run it now.
468479
// After running the warmup phase the BenchmarkRunner should be in a state as
469480
// this warmup never happened except the fact that warmup_done is set. Every

0 commit comments

Comments
 (0)