Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions src/benchmark.cc
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ BM_DEFINE_bool(benchmark_counters_tabular, false);
// information about libpfm: https://man7.org/linux/man-pages/man3/libpfm.3.html
BM_DEFINE_string(benchmark_perf_counters, "");

// Setting this to false allows measuring only the main benchmark thread.
BM_DEFINE_bool(benchmark_perf_counters_inherit, true);

// Extra context to include in the output formatted as comma-separated key-value
// pairs. Kept internal as it's only used for parsing from env/command line.
BM_DEFINE_kvpairs(benchmark_context, {});
Expand Down Expand Up @@ -424,7 +427,8 @@ void RunBenchmarks(const std::vector<BenchmarkInstance>& benchmarks,
// This perfcounters object needs to be created before the runners vector
// below so it outlasts their lifetime.
PerfCountersMeasurement perfcounters(
StrSplit(FLAGS_benchmark_perf_counters, ','));
StrSplit(FLAGS_benchmark_perf_counters, ','),
FLAGS_benchmark_perf_counters_inherit);

// Vector of benchmarks to run
std::vector<internal::BenchmarkRunner> runners;
Expand Down Expand Up @@ -453,7 +457,8 @@ void RunBenchmarks(const std::vector<BenchmarkInstance>& benchmarks,

// The use of performance counters with threads would be unintuitive for
// the average user so we need to warn them about this case
if ((benchmarks_with_threads > 0) && (perfcounters.num_counters() > 0)) {
if ((benchmarks_with_threads > 0) && (perfcounters.num_counters() > 0) &&
FLAGS_benchmark_perf_counters_inherit) {
GetErrorLogInstance()
<< "***WARNING*** There are " << benchmarks_with_threads
<< " benchmarks with threads and " << perfcounters.num_counters()
Expand Down Expand Up @@ -770,6 +775,8 @@ void ParseCommandLineFlags(int* argc, char** argv) {
&FLAGS_benchmark_report_aggregates_only) ||
ParseBoolFlag(argv[i], "benchmark_display_aggregates_only",
&FLAGS_benchmark_display_aggregates_only) ||
ParseBoolFlag(argv[i], "benchmark_perf_counters_inherit",
&FLAGS_benchmark_perf_counters_inherit) ||
ParseStringFlag(argv[i], "benchmark_format", &FLAGS_benchmark_format) ||
ParseStringFlag(argv[i], "benchmark_out", &FLAGS_benchmark_out) ||
ParseStringFlag(argv[i], "benchmark_out_format",
Expand Down Expand Up @@ -891,6 +898,7 @@ void PrintDefaultHelp() {
" [--benchmark_counters_tabular={true|false}]\n"
#if defined HAVE_LIBPFM
" [--benchmark_perf_counters=<counter>,...]\n"
" [--benchmark_perf_counters_inherit={true|false}]\n" // <--- Add this
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the AI generated comment please

#endif
" [--benchmark_context=<key>=<value>,...]\n"
" [--benchmark_time_unit={ns|us|ms|s}]\n"
Expand Down
12 changes: 7 additions & 5 deletions src/perf_counters.cc
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ static std::vector<uint64_t> GetPMUTypesForEvent(const perf_event_attr& attr) {
}

PerfCounters PerfCounters::Create(
const std::vector<std::string>& counter_names) {
const std::vector<std::string>& counter_names, bool inherit) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

boolean parameters are notoriously hard to track as the callsite becomes opaque : https://abseil.io/tips/94

if (!counter_names.empty()) {
Initialize();
}
Expand Down Expand Up @@ -202,8 +202,9 @@ PerfCounters PerfCounters::Create(
// Note: the man page for perf_event_create suggests inherit = true and
// read_format = PERF_FORMAT_GROUP don't work together, but that's not the
// case.

attr.disabled = is_first;
attr.inherit = true;
attr.inherit = inherit;
attr.pinned = is_first;
attr.exclude_kernel = true;
attr.exclude_user = false;
Expand Down Expand Up @@ -311,20 +312,21 @@ bool PerfCounters::Initialize() { return false; }
bool PerfCounters::IsCounterSupported(const std::string&) { return false; }

PerfCounters PerfCounters::Create(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this would be clearer as two methods: Create and CreateInherited (or whatever naming you land on)

const std::vector<std::string>& counter_names) {
const std::vector<std::string>& counter_names, bool inherit) {
if (!counter_names.empty()) {
GetErrorLogInstance() << "Performance counters not supported.\n";
}
(void)inherit; // This just tells the compiler to ignore the variable
return NoCounters();
}

void PerfCounters::CloseCounters() const {}
#endif // defined HAVE_LIBPFM

PerfCountersMeasurement::PerfCountersMeasurement(
const std::vector<std::string>& counter_names)
const std::vector<std::string>& counter_names, bool inherit)
: start_values_(counter_names.size()), end_values_(counter_names.size()) {
counters_ = PerfCounters::Create(counter_names);
counters_ = PerfCounters::Create(counter_names, inherit);
}

PerfCounters& PerfCounters::operator=(PerfCounters&& other) noexcept {
Expand Down
4 changes: 2 additions & 2 deletions src/perf_counters.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class BENCHMARK_EXPORT PerfCounters final {
// implementation and OS specific.
// In case of failure, this method will in the worst case return an
// empty object whose state will still be valid.
static PerfCounters Create(const std::vector<std::string>& counter_names);
static PerfCounters Create(const std::vector<std::string>& counter_names, bool inherit = true);

// Take a snapshot of the current value of the counters into the provided
// valid PerfCounterValues storage. The values are populated such that:
Expand Down Expand Up @@ -148,7 +148,7 @@ class BENCHMARK_EXPORT PerfCounters final {
// Typical usage of the above primitives.
class BENCHMARK_EXPORT PerfCountersMeasurement final {
public:
PerfCountersMeasurement(const std::vector<std::string>& counter_names);
PerfCountersMeasurement(const std::vector<std::string>& counter_names, bool inherit);

size_t num_counters() const { return counters_.num_counters(); }

Expand Down