CppBenchmark 1.0.5.0
C++ Benchmark Library
Loading...
Searching...
No Matches
phase_metrics.cpp
Go to the documentation of this file.
1
10
11#include "benchmark/system.h"
12
13#include <algorithm>
14#include <cstdlib>
15
16#if defined(_MSC_VER)
17#include <intrin.h>
18#endif
19
20#include <hdr/hdr_histogram.h>
21
22namespace CppBenchmark {
23
24PhaseMetrics::PhaseMetrics() : _histogram(nullptr)
25{
26 ResetMetrics();
27}
28
30{
31 FreeLatencyHistogram();
32}
33
34bool PhaseMetrics::latency() const noexcept
35{
36 return (_histogram != nullptr);
37}
38
39int64_t PhaseMetrics::min_latency() const noexcept
40{
41 return latency() ? hdr_min((const hdr_histogram*)_histogram) : 0;
42}
43
44int64_t PhaseMetrics::max_latency() const noexcept
45{
46 return latency() ? hdr_max((const hdr_histogram*)_histogram) : 0;
47}
48
49double PhaseMetrics::mean_latency() const noexcept
50{
51 return latency() ? hdr_mean((const hdr_histogram*)_histogram) : 0;
52}
53
54double PhaseMetrics::stdv_latency() const noexcept
55{
56 return latency() ? hdr_stddev((const hdr_histogram*)_histogram) : 0;
57}
58
59int64_t PhaseMetrics::avg_time() const noexcept
60{
61 return (_total_operations > 0) ? (_total_time / _total_operations) : 0;
62}
63
64int64_t PhaseMetrics::min_time() const noexcept
65{
66 return _min_time;
67}
68
69int64_t PhaseMetrics::max_time() const noexcept
70{
71 return _max_time;
72}
73
75{
76 if (_total_time <= 0)
77 return 0;
78
79 return System::MulDiv64(_total_operations, 1000000000, _total_time);
80}
81
82int64_t PhaseMetrics::items_per_second() const noexcept
83{
84 if (_total_time <= 0)
85 return 0;
86
87 return System::MulDiv64(_total_items, 1000000000, _total_time);
88}
89
90int64_t PhaseMetrics::bytes_per_second() const noexcept
91{
92 if (_total_time <= 0)
93 return 0;
94
95 return System::MulDiv64(_total_bytes, 1000000000, _total_time);
96}
97
98void PhaseMetrics::InitLatencyHistogram(const std::tuple<int64_t, int64_t, int>& latency) noexcept
99{
100 int64_t lowest = std::get<0>(latency);
101 int64_t highest = std::get<1>(latency);
102 int significant = std::get<2>(latency);
103
104 FreeLatencyHistogram();
105 int result = hdr_init(lowest, highest, significant, ((hdr_histogram**)&_histogram));
106 if (result != 0)
107 _histogram = nullptr;
108}
109
110void PhaseMetrics::PrintLatencyHistogram(FILE* file, int32_t resolution) const noexcept
111{
112 if ((_histogram != nullptr) && (file != nullptr))
113 {
114 hdr_percentiles_print((hdr_histogram*)_histogram, file, resolution, 1.0, CLASSIC);
115 }
116}
117
118void PhaseMetrics::FreeLatencyHistogram() noexcept
119{
120 if (_histogram != nullptr)
121 {
122 hdr_close((hdr_histogram*)_histogram);
123 _histogram = nullptr;
124 }
125}
126
127void PhaseMetrics::AddLatency(int64_t latency) noexcept
128{
129 if (_histogram != nullptr)
130 hdr_record_values((hdr_histogram*)_histogram, latency, 1);
131}
132
133void PhaseMetrics::StartCollecting() noexcept
134{
135 _iterstamp = _total_operations;
136 _timestamp = System::Timestamp();
137}
138
139void PhaseMetrics::StopCollecting() noexcept
140{
141 // Get iterations count & duration of the phase
142 int64_t iterations = _total_operations - _iterstamp;
143 int64_t duration = System::Timestamp() - _timestamp;
144
145 // Get min & max time of the phase
146 int64_t min_time = (iterations > 0) ? (duration / iterations) : std::numeric_limits<int64_t>::max();
147 int64_t max_time = (iterations > 0) ? (duration / iterations) : std::numeric_limits<int64_t>::min();
148
149 // Update time counters
150 if (min_time < _min_time)
151 _min_time = min_time;
152 if (max_time > _max_time)
153 _max_time = max_time;
154 _total_time += duration;
155}
156
157void PhaseMetrics::MergeMetrics(PhaseMetrics& metrics)
158{
159 // Choose best min time
160 if (metrics._min_time < _min_time)
161 _min_time = metrics._min_time;
162
163 // Choose best max time
164 if (metrics._max_time > _max_time)
165 _max_time = metrics._max_time;
166
167 // Merge custom hash tables
168 _custom_int.insert(metrics._custom_int.begin(), metrics._custom_int.end());
169 _custom_uint.insert(metrics._custom_uint.begin(), metrics._custom_uint.end());
170 _custom_int64.insert(metrics._custom_int64.begin(), metrics._custom_int64.end());
171 _custom_uint64.insert(metrics._custom_uint64.begin(), metrics._custom_uint64.end());
172 _custom_flt.insert(metrics._custom_flt.begin(), metrics._custom_flt.end());
173 _custom_dbl.insert(metrics._custom_dbl.begin(), metrics._custom_dbl.end());
174 _custom_str.insert(metrics._custom_str.begin(), metrics._custom_str.end());
175
176 // Choose best total time with operations, items and bytes
177 if (metrics._total_time < _total_time)
178 {
179 std::swap(_histogram, metrics._histogram);
180 _total_time = metrics._total_time;
181 _total_operations = metrics._total_operations;
182 _total_items = metrics._total_items;
183 _total_bytes = metrics._total_bytes;
184
185 // Overwrite metrics custom tables
186 for (const auto& it : metrics._custom_int)
187 _custom_int[it.first] = it.second;
188 for (const auto& it : metrics._custom_uint)
189 _custom_uint[it.first] = it.second;
190 for (const auto& it : metrics._custom_int64)
191 _custom_int64[it.first] = it.second;
192 for (const auto& it : metrics._custom_uint64)
193 _custom_uint64[it.first] = it.second;
194 for (const auto& it : metrics._custom_flt)
195 _custom_flt[it.first] = it.second;
196 for (const auto& it : metrics._custom_dbl)
197 _custom_dbl[it.first] = it.second;
198 for (const auto& it : metrics._custom_str)
199 _custom_str[it.first] = it.second;
200
201 // Overwrite metrics threads value
202 _threads = metrics._threads;
203 }
204}
205
206void PhaseMetrics::ResetMetrics() noexcept
207{
208 FreeLatencyHistogram();
209 _min_time = std::numeric_limits<int64_t>::max();
210 _max_time = std::numeric_limits<int64_t>::min();
211 _total_time = 0;
212 _total_operations = 0;
213 _total_items = 0;
214 _total_bytes = 0;
215 _iterstamp = 0;
216 _timestamp = 0;
217 _threads = 1;
218}
219
220} // namespace CppBenchmark
double mean_latency() const noexcept
Get latency mean value of the phase execution.
int64_t min_time() const noexcept
Get minimal time of the phase execution.
int64_t min_latency() const noexcept
Get latency minimal value of the phase execution.
double stdv_latency() const noexcept
Get latency standard deviation of the phase execution.
int64_t max_latency() const noexcept
Get latency maximal value of the phase execution.
int64_t avg_time() const noexcept
Get average time of the phase execution.
int64_t max_time() const noexcept
Get maximal time of the phase execution.
void AddLatency(int64_t latency) noexcept
Add latency value of the current phase.
int64_t bytes_per_second() const noexcept
Get data throughput (bytes / second)
int64_t items_per_second() const noexcept
Get items throughput (items / second)
int64_t operations_per_second() const noexcept
Get operations throughput (operations / second)
PhaseMetrics()
Default constructor.
bool latency() const noexcept
Is metrics contains latency values?
static uint64_t Timestamp()
Get the current timestamp in nanoseconds.
Definition system.cpp:399
static uint64_t MulDiv64(uint64_t operant, uint64_t multiplier, uint64_t divider)
Calculate (operant * multiplier / divider) with 64-bit unsigned integer values.
Definition system.cpp:450
C++ Benchmark project definitions.
Definition barrier.h:15
Benchmark phase metrics definition.
System management definition.