Botan 3.6.1
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 const uint64_t now = OS::get_system_timestamp_ns();
53
54 if(now > m_timer_start) {
55 m_time_used += (now - m_timer_start);
56 }
57
58 if(m_cpu_cycles_start != 0) {
59 const uint64_t cycles_taken = OS::get_cpu_cycle_counter() - m_cpu_cycles_start;
60 if(cycles_taken > 0) {
61 m_cpu_cycles_used += static_cast<size_t>(cycles_taken * m_clock_cycle_ratio);
62 }
63 }
64
65 m_timer_start = 0;
66 ++m_event_count;
67 }
68}
69
70bool Timer::operator<(const Timer& other) const {
71 if(this->doing() != other.doing()) {
72 return (this->doing() < other.doing());
73 }
74
75 return (this->get_name() < other.get_name());
76}
77
78std::string Timer::to_string() const {
79 if(!m_custom_msg.empty()) {
80 return m_custom_msg;
81 } else if(this->buf_size() == 0) {
82 return result_string_ops();
83 } else {
84 return result_string_bps();
85 }
86}
87
88std::string Timer::result_string_bps() const {
89 const size_t MiB = 1024 * 1024;
90
91 const double MiB_total = static_cast<double>(events()) / MiB;
92 const double MiB_per_sec = MiB_total / seconds();
93
94 std::ostringstream oss;
95 oss << get_name();
96
97 if(!doing().empty()) {
98 oss << " " << doing();
99 }
100
101 if(buf_size() > 0) {
102 oss << " buffer size " << buf_size() << " bytes:";
103 }
104
105 if(events() == 0) {
106 oss << " "
107 << "N/A";
108 } else {
109 oss << " " << std::fixed << std::setprecision(3) << MiB_per_sec << " MiB/sec";
110 }
111
112 if(cycles_consumed() != 0) {
113 const double cycles_per_byte = static_cast<double>(cycles_consumed()) / events();
114 oss << " " << std::fixed << std::setprecision(2) << cycles_per_byte << " cycles/byte";
115 }
116
117 oss << " (" << MiB_total << " MiB in " << milliseconds() << " ms)\n";
118
119 return oss.str();
120}
121
122std::string Timer::result_string_ops() const {
123 std::ostringstream oss;
124
125 oss << get_name() << " ";
126
127 if(events() == 0) {
128 oss << "no events\n";
129 } else {
130 oss << static_cast<uint64_t>(events_per_second()) << ' ' << doing() << "/sec; " << std::setprecision(2)
131 << std::fixed << ms_per_event() << " ms/op";
132
133 if(cycles_consumed() != 0) {
134 const double cycles_per_op = static_cast<double>(cycles_consumed()) / events();
135 const int precision = (cycles_per_op < 10000) ? 2 : 0;
136 oss << " " << std::fixed << std::setprecision(precision) << cycles_per_op << " cycles/op";
137 }
138
139 oss << " (" << events() << " " << (events() == 1 ? "op" : "ops") << " in " << milliseconds() << " ms)\n";
140 }
141
142 return oss.str();
143}
144
145} // namespace Botan
bool operator<(const Timer &other) const
Definition timer.cpp:70
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:78
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:329
uint64_t BOTAN_TEST_API get_cpu_cycle_counter()
Definition os_utils.cpp:190