Botan 3.5.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
9#include <botan/internal/os_utils.h>
10#include <algorithm>
11#include <iomanip>
12#include <sstream>
13
14namespace Botan {
15
16namespace {
17
18std::string format_timer_name(std::string_view name, std::string_view provider) {
19 if(provider.empty() || provider == "base") {
20 return std::string(name);
21 }
22
23 std::ostringstream out;
24 out << name << " [" << provider << "]";
25 return out.str();
26}
27
28} // namespace
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
45 stop();
46 m_timer_start = OS::get_system_timestamp_ns();
47 m_cpu_cycles_start = OS::get_cpu_cycle_counter();
48}
49
51 if(m_timer_start) {
52 if(m_cpu_cycles_start != 0) {
53 const uint64_t cycles_taken = OS::get_cpu_cycle_counter() - m_cpu_cycles_start;
54 if(cycles_taken > 0) {
55 m_cpu_cycles_used += static_cast<size_t>(cycles_taken * m_clock_cycle_ratio);
56 }
57 }
58
59 const uint64_t now = OS::get_system_timestamp_ns();
60
61 if(now > m_timer_start) {
62 const uint64_t dur = now - m_timer_start;
63
64 m_time_used += dur;
65
66 if(m_event_count == 0) {
67 m_min_time = m_max_time = dur;
68 } else {
69 m_max_time = std::max(m_max_time, dur);
70 m_min_time = std::min(m_min_time, dur);
71 }
72 }
73
74 m_timer_start = 0;
75 ++m_event_count;
76 }
77}
78
79bool Timer::operator<(const Timer& other) const {
80 if(this->doing() != other.doing()) {
81 return (this->doing() < other.doing());
82 }
83
84 return (this->get_name() < other.get_name());
85}
86
87std::string Timer::to_string() const {
88 if(!m_custom_msg.empty()) {
89 return m_custom_msg;
90 } else if(this->buf_size() == 0) {
91 return result_string_ops();
92 } else {
93 return result_string_bps();
94 }
95}
96
97std::string Timer::result_string_bps() const {
98 const size_t MiB = 1024 * 1024;
99
100 const double MiB_total = static_cast<double>(events()) / MiB;
101 const double MiB_per_sec = MiB_total / seconds();
102
103 std::ostringstream oss;
104 oss << get_name();
105
106 if(!doing().empty()) {
107 oss << " " << doing();
108 }
109
110 if(buf_size() > 0) {
111 oss << " buffer size " << buf_size() << " bytes:";
112 }
113
114 if(events() == 0) {
115 oss << " "
116 << "N/A";
117 } else {
118 oss << " " << std::fixed << std::setprecision(3) << MiB_per_sec << " MiB/sec";
119 }
120
121 if(cycles_consumed() != 0) {
122 const double cycles_per_byte = static_cast<double>(cycles_consumed()) / events();
123 oss << " " << std::fixed << std::setprecision(2) << cycles_per_byte << " cycles/byte";
124 }
125
126 oss << " (" << MiB_total << " MiB in " << milliseconds() << " ms)\n";
127
128 return oss.str();
129}
130
131std::string Timer::result_string_ops() const {
132 std::ostringstream oss;
133
134 oss << get_name() << " ";
135
136 if(events() == 0) {
137 oss << "no events\n";
138 } else {
139 oss << static_cast<uint64_t>(events_per_second()) << ' ' << doing() << "/sec; " << std::setprecision(2)
140 << std::fixed << ms_per_event() << " ms/op";
141
142 if(cycles_consumed() != 0) {
143 const double cycles_per_op = static_cast<double>(cycles_consumed()) / events();
144 const int precision = (cycles_per_op < 10000) ? 2 : 0;
145 oss << " " << std::fixed << std::setprecision(precision) << cycles_per_op << " cycles/op";
146 }
147
148 oss << " (" << events() << " " << (events() == 1 ? "op" : "ops") << " in " << milliseconds() << " ms)\n";
149 }
150
151 return oss.str();
152}
153
154} // namespace Botan
bool operator<(const Timer &other) const
Definition timer.cpp:79
double milliseconds() const
Definition timer.h:70
double events_per_second() const
Definition timer.h:91
void start()
Definition timer.cpp:44
uint64_t cycles_consumed() const
Definition timer.h:74
double ms_per_event() const
Definition timer.h:72
std::string to_string() const
Definition timer.cpp:87
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:50
const std::string & get_name() const
Definition timer.h:83
size_t buf_size() const
Definition timer.h:87
uint64_t events() const
Definition timer.h:81
const std::string & doing() const
Definition timer.h:85
double seconds() const
Definition timer.h:68
std::string name
uint64_t BOTAN_TEST_API get_system_timestamp_ns()
Definition os_utils.cpp:318
uint64_t BOTAN_TEST_API get_cpu_cycle_counter()
Definition os_utils.cpp:179