Botan 3.0.0
Crypto and TLS for C&
timer.cpp
Go to the documentation of this file.
1/*
2* (C) 2018 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#include <botan/internal/timer.h>
8#include <botan/internal/os_utils.h>
9#include <algorithm>
10#include <sstream>
11#include <iomanip>
12
13namespace Botan {
14
15namespace {
16
17std::string format_timer_name(std::string_view name,
18 std::string_view provider)
19 {
20 if(provider.empty() || provider == "base")
21 return std::string(name);
22
23 std::ostringstream out;
24 out << name << " [" << provider << "]";
25 return out.str();
26 }
27
28}
29
30Timer::Timer(std::string_view name,
31 std::string_view provider,
32 std::string_view doing,
33 uint64_t event_mult,
34 size_t buf_size,
35 double clock_cycle_ratio,
36 uint64_t clock_speed)
37 : m_name(format_timer_name(name, provider))
38 , m_doing(doing)
39 , m_buf_size(buf_size)
40 , m_event_mult(event_mult)
41 , m_clock_cycle_ratio(clock_cycle_ratio)
42 , m_clock_speed(clock_speed)
43 {}
44
46 {
47 stop();
48 m_timer_start = OS::get_system_timestamp_ns();
49 m_cpu_cycles_start = OS::get_cpu_cycle_counter();
50 }
51
53 {
54 if(m_timer_start)
55 {
56 if(m_cpu_cycles_start != 0)
57 {
58 const uint64_t cycles_taken = OS::get_cpu_cycle_counter() - m_cpu_cycles_start;
59 if(cycles_taken > 0)
60 {
61 m_cpu_cycles_used += static_cast<size_t>(cycles_taken * m_clock_cycle_ratio);
62 }
63 }
64
65 const uint64_t now = OS::get_system_timestamp_ns();
66
67 if(now > m_timer_start)
68 {
69 const uint64_t dur = now - m_timer_start;
70
71 m_time_used += dur;
72
73 if(m_event_count == 0)
74 {
75 m_min_time = m_max_time = dur;
76 }
77 else
78 {
79 m_max_time = std::max(m_max_time, dur);
80 m_min_time = std::min(m_min_time, dur);
81 }
82 }
83
84 m_timer_start = 0;
85 ++m_event_count;
86 }
87 }
88
89bool Timer::operator<(const Timer& other) const
90 {
91 if(this->doing() != other.doing())
92 return (this->doing() < other.doing());
93
94 return (this->get_name() < other.get_name());
95 }
96
97std::string Timer::to_string() const
98 {
99 if(!m_custom_msg.empty())
100 {
101 return m_custom_msg;
102 }
103 else if(this->buf_size() == 0)
104 {
105 return result_string_ops();
106 }
107 else
108 {
109 return result_string_bps();
110 }
111 }
112
113std::string Timer::result_string_bps() const
114 {
115 const size_t MiB = 1024 * 1024;
116
117 const double MiB_total = static_cast<double>(events()) / MiB;
118 const double MiB_per_sec = MiB_total / seconds();
119
120 std::ostringstream oss;
121 oss << get_name();
122
123 if(!doing().empty())
124 {
125 oss << " " << doing();
126 }
127
128 if(buf_size() > 0)
129 {
130 oss << " buffer size " << buf_size() << " bytes:";
131 }
132
133 if(events() == 0)
134 oss << " " << "N/A";
135 else
136 oss << " " << std::fixed << std::setprecision(3) << MiB_per_sec << " MiB/sec";
137
138 if(cycles_consumed() != 0)
139 {
140 const double cycles_per_byte = static_cast<double>(cycles_consumed()) / events();
141 oss << " " << std::fixed << std::setprecision(2) << cycles_per_byte << " cycles/byte";
142 }
143
144 oss << " (" << MiB_total << " MiB in " << milliseconds() << " ms)\n";
145
146 return oss.str();
147 }
148
149std::string Timer::result_string_ops() const
150 {
151 std::ostringstream oss;
152
153 oss << get_name() << " ";
154
155 if(events() == 0)
156 {
157 oss << "no events\n";
158 }
159 else
160 {
161 oss << static_cast<uint64_t>(events_per_second())
162 << ' ' << doing() << "/sec; "
163 << std::setprecision(2) << std::fixed
164 << ms_per_event() << " ms/op";
165
166 if(cycles_consumed() != 0)
167 {
168 const double cycles_per_op = static_cast<double>(cycles_consumed()) / events();
169 const int precision = (cycles_per_op < 10000) ? 2 : 0;
170 oss << " " << std::fixed << std::setprecision(precision) << cycles_per_op << " cycles/op";
171 }
172
173 oss << " (" << events() << " " << (events() == 1 ? "op" : "ops")
174 << " in " << milliseconds() << " ms)\n";
175 }
176
177 return oss.str();
178 }
179
180}
bool operator<(const Timer &other) const
Definition: timer.cpp:89
double milliseconds() const
Definition: timer.h:94
double events_per_second() const
Definition: timer.h:138
void start()
Definition: timer.cpp:45
uint64_t cycles_consumed() const
Definition: timer.h:104
double ms_per_event() const
Definition: timer.h:99
std::string to_string() const
Definition: timer.cpp:97
const std::string doing() const
Definition: timer.h:123
Timer(std::string_view name, std::string_view provider, std::string_view doing, uint64_t event_mult, size_t buf_size, double clock_cycle_ratio, uint64_t clock_speed)
Definition: timer.cpp:30
void stop()
Definition: timer.cpp:52
size_t buf_size() const
Definition: timer.h:128
uint64_t events() const
Definition: timer.h:113
double seconds() const
Definition: timer.h:89
const std::string get_name() const
Definition: timer.h:118
std::string name
uint64_t BOTAN_TEST_API get_system_timestamp_ns()
Definition: os_utils.cpp:320
uint64_t BOTAN_TEST_API get_cpu_cycle_counter()
Definition: os_utils.cpp:177
Definition: alg_id.cpp:12