51class BENCHMARK_EXPORT PerfCounterValues {
53 explicit PerfCounterValues(
size_t nr_counters) : nr_counters_(nr_counters) {
54 BM_CHECK_LE(nr_counters_, kMaxCounters);
58 uint64_t operator[](
size_t pos)
const {
return values_[pos]; }
62 static constexpr size_t kMaxCounters = 32;
65 friend class PerfCounters;
68 std::pair<char*, size_t> get_data_buffer() {
69 return {
reinterpret_cast<char*
>(values_.data()),
70 sizeof(uint64_t) * (kPadding + nr_counters_)};
76 size_t Read(
const std::vector<int>& leaders);
80 static constexpr size_t kPadding = 2;
81 std::array<uint64_t, kPadding + kMaxCounters> values_;
82 const size_t nr_counters_;
88class BENCHMARK_EXPORT PerfCounters final {
91 static const bool kSupported;
94 static PerfCounters NoCounters() {
return PerfCounters(); }
96 ~PerfCounters() { CloseCounters(); }
97 PerfCounters() =
default;
98 PerfCounters(PerfCounters&&) =
default;
99 PerfCounters(
const PerfCounters&) =
delete;
100 PerfCounters& operator=(PerfCounters&&)
noexcept;
101 PerfCounters& operator=(
const PerfCounters&) =
delete;
105 static bool Initialize();
109 static bool IsCounterSupported(
const std::string& name);
116 static PerfCounters Create(
const std::vector<std::string>& counter_names);
122#ifndef BENCHMARK_OS_WINDOWS
123 assert(values !=
nullptr);
124 return values->Read(leader_ids_) == counter_ids_.size();
131 const std::vector<std::string>& names()
const {
return counter_names_; }
132 size_t num_counters()
const {
return counter_names_.size(); }
135 PerfCounters(
const std::vector<std::string>& counter_names,
136 std::vector<int>&& counter_ids, std::vector<int>&& leader_ids)
137 : counter_ids_(std::move(counter_ids)),
138 leader_ids_(std::move(leader_ids)),
139 counter_names_(counter_names) {}
141 void CloseCounters()
const;
143 std::vector<int> counter_ids_;
144 std::vector<int> leader_ids_;
145 std::vector<std::string> counter_names_;
149class BENCHMARK_EXPORT PerfCountersMeasurement final {
151 PerfCountersMeasurement(
const std::vector<std::string>& counter_names);
153 size_t num_counters()
const {
return counters_.num_counters(); }
155 std::vector<std::string> names()
const {
return counters_.names(); }
157 BENCHMARK_ALWAYS_INLINE
bool Start() {
158 if (num_counters() == 0)
return true;
162 valid_read_ &= counters_.Snapshot(&start_values_);
168 BENCHMARK_ALWAYS_INLINE
bool Stop(
169 std::vector<std::pair<std::string, double>>& measurements) {
170 if (num_counters() == 0)
return true;
174 valid_read_ &= counters_.Snapshot(&end_values_);
177 for (
size_t i = 0; i < counters_.names().size(); ++i) {
178 double measurement =
static_cast<double>(end_values_[i]) -
179 static_cast<double>(start_values_[i]);
180 measurements.push_back({counters_.names()[i], measurement});
188 bool valid_read_ =
true;