Timing¶
Timing, namely to measure the run-time of a piece of code, is a common
practice in development, especially in contexts where performance is critical
(e.g. numerical computation). CLUE++ provides timing facilities to
facilitate this practice. All these facilities are in the namespace clue
.
Representation of duration¶
A class duration
is introduced to represent time durations.
-
class
duration
¶ A wrapper of
std::chrono::high_resolution_clock::duration
that exposes more user friendly interface to work with duration.
The stop_watch
class use a duration
object to represent the elapsed
time. The duration
class has several member functions to retrieve the
duration in different units.
-
explicit constexpr
duration
() noexcept¶ Construct a zero duration.
-
constexpr
duration
(const value_type &val) noexcept¶ Construct a duration with an object of class
value_type
, namelystd::chrono::high_resolution_clock::duration
.
-
constexpr double
get
() const noexcept¶ dur.get<U>()
gets the duration in unitU
. Here,U
should be an instantiation of the class templatestd::ratio
.The following table lists the correspondence between
U
and physical time units.type U
physical unit std::ratio<1>
seconds std::milli
milliseconds std::micro
microseconds std::nano
nanoseconds std::ratio<60>
minutes std::ratio<3600>
hours
A set of convenient member functions are also provided to make this a bit easier:
-
constexpr double
secs
() const noexcept¶ Get the duration in seconds.
-
constexpr double
msecs
() const noexcept¶ Get the duration in milliseconds.
-
constexpr double
usecs
() const noexcept¶ Get the duration in microseconds.
-
constexpr double
nsecs
() const noexcept¶ Get the duration in nanoseconds.
-
constexpr double
mins
() const noexcept¶ Get the duration in minutes.
-
constexpr double
hours
() const noexcept¶ Get the duration in minutes.
Stopwatch¶
A stop_watch
class is introduced to measure running time.
-
class
stop_watch
¶ Stop watch class for measuring run-time, in wall-clock sense.
Note: Internally, it relies on the class std::chrono::high_resolution_clock
introduced in C++11 for timing, and hence it is highly portable.
The class stop_watch
has the following members:
-
explicit
stop_watch
(bool st = false) noexcept¶ Construct a stop watch. By default, it is not started. One can set
st
totrue
to let the stop watch starts upon construction.
-
void
reset
() noexcept¶ Reset the watch: stop it and clear the accumulated elapsed duration.
-
void
start
() noexcept¶ Start or resume the watch.
-
void
stop
() noexcept¶ Stop the watch and accumulates the duration of last run to the total elapsed duration.
Here is an example to illustrate the use of the stop_watch
class.
#include <clue/timing.hpp>
using namespace clue;
// simple use
stop_watch sw(true); // starts upon construction
run_my_code();
std::cout << sw.elapsed().secs() << std::endl;
// multiple laps
stop_watch sw1;
for (size_t i = 0; i < 10; ++i) {
sw1.start();
run_my_code();
sw1.stop();
std::cout << "cumulative elapsed = "
<< sw1.elapsed().secs() << std::endl;
}
Timing functions¶
We also provide convenient functions to help people time a certain function.
-
duration
simple_time
(F &&f, size_t n, size_t n0 = 0)¶ Run the function
f()
forn
times and return the total elapsed duration.Parameters: - f – The function to be timed.
- n – The number of times
f
is to be executed. - n0 – The number of pre-running times. If
n0 > 0
, it will pre-runf
forn0
times to warm up the function (for certain functions, the first run or first several runs may take substantially longer time).
-
calibrated_timing_result
calibrated_time
(F &&f, double measure_secs = 1.0, double calib_secs = 1.0e-4)¶ Calibrated timing.
This function may spend a little bit time (around
calib_secs
seconds) to roughly measure the average running time off()
(i.e. calibaration), and then runf()
for more times for actual measurement such that the entire duration of measurement is aroundmeasure_secs
seconds.Parameters: - f – The function to be timed.
- measure_secs – The time to be spent on actual measurement (in seconds).
- calib_secs – The time to be spent on calibration (in seconds).
Returns: the timing result of class
calibrated_timing_result
.
-
class
calibrated_timing_result
¶ A struct to represent the result of calibrated timing, which has two fields:
count_runs
: the number of runs in actual timing.elapsed_secs
: elapsed duration of the actual timing process, in seconds.
Examples:
// source file: examples/ex_timing.hpp
#include <clue/timing.hpp>
#include <cstdio>
#include <cstring>
using namespace clue;
static char src[1000000];
static char dst[1000000];
void unused(char c) {}
// copy 1 million bytes
void copy1M() {
std::memcpy(dst, src, sizeof(src));
// ensure the copy actually happens in optimized code
volatile char v = dst[0];
unused(v); // suppress unused warning
}
int main() {
std::memset(src, 0, sizeof(src));
auto r = calibrated_time(copy1M);
std::printf("Result:\n");
std::printf(" runs = %zu\n", r.count_runs);
std::printf(" elapsed = %.4f secs\n", r.elapsed_secs);
double gps = r.count_runs * 1.0e-3 / r.elapsed_secs;
std::printf(" speed = %.4f Gbytes/sec\n", gps);
return 0;
}