CHRONO LIBRARY
Based on Nikolai Josuttis
http:
<chrono>
switch from seconds -> miliseconds -> nanoseconds required new interface.
Timers & clocks might be different on difefrent systems and mey be improved.
Precision-neutral library to measure date & time.
Separating duration & timepoint from clock(s)
Duration:
Span of time, #ticks of some time unit,
e.g. 42 sec == 42 tick of 1-sec unit.
Timepoint:
A duration + epoch (beginning of time), parameterized by clock
e.g. 1,262,300,400 seconds since January 1, 1970 == 2000.1.1.
Clock:
Clock defines the epoch of the timepoint. Different clocks have different epoch.
Operation on timepoint, e.g. processing duration, requires the same clock.
Duration
========
std::chrono
{
template <class Rep, class Period = std::ratio<1>>
class duration;
}
std::chrono::duration<int> twentySeconds(20);
std::chrono::duration<double,std::ratio<60>> halfMinute(0.5);
std::chrono::duration<long,std::ratio<1,1000>> oneMillisecond(1);
#include <ratio>
template< std::intmax_t Num, std::intmax_t Denom = 1 >
class ratio
{
constexpr intmax_t num();
constexpr intmax_t den();
typedef std::ratio<1, 1000000000000000000000000> yocto;
...
typedef std::ratio<1, 10> deci
typedef std::ratio<10, 1> deca;
...
};
namespace std {
namespace chrono {
typedef duration<signed int-type >= 64 bits,nano> nanoseconds;
typedef duration<signed int-type >= 55 bits,micro> microseconds;
typedef duration<signed int-type >= 45 bits,milli> milliseconds;
typedef duration<signed int-type >= 35 bits> seconds;
typedef duration<signed int-type >= 29 bits,ratio<60>> minutes;
typedef duration<signed int-type >= 23 bits,ratio<3600>> hours;
}
}
std::chrono::seconds twentySeconds(20);
std::chrono::hours aDay(24);
std::chrono::milliseconds oneMillisecond(1);
There are arithmetic operations on Duration:
--------------------------------------------
d1 + d2
d1 - d2
d * val
d / val
d1 / d2
d % val
d1 % d2
d1 == d2
d1 != d2
d1 < d2
++d (increment by 1 tick)
...
chrono::seconds d1(42);
chrono::milliseconds d2(10);
d1 - d2
std::chrono::seconds twentySeconds(20);
std::chrono::hours aDay(24);
std::chrono::milliseconds ms;
ms += twentySeconds + aDay;
--ms;
ms *= 2;
std::cout << ms.count() << " ms" << std::endl;
std::cout << std::chrono::nanoseconds(ms).count() << " ns" << std::endl;
172839998 ms
172839998000000 ns
d.count()
D d2 = duration_cast<D>(d);
duration::zero()
typedef ... duration::rep
typedef ... duration::period
template <typename V, typename R>
ostream& operator << (ostream& s, const chrono::duration<V,R>& d)
{
s << "[" << d.count() << " of " << R::num << "/"
<< R::den << "]";
return s;
}
std::chrono::milliseconds d(42);
std::cout << d << std::endl;
[42 of 1/1000]
std::chrono::duration<double,std::ratio<60>> halfMin(0.5);
std::chrono::seconds s1 = halfMin;
std::chrono::seconds s2 =
std::chrono::duration_cast<std::chrono::seconds>(halfMin);
using namespace std;
using namespace std::chrono;
milliseconds ms(7255042);
hours hh = duration_cast<hours>(ms);
minutes mm = duration_cast<minutes>(ms % chrono::hours(1));
seconds ss = duration_cast<seconds>(ms % chrono::minutes(1));
milliseconds msec = duration_cast<milliseconds>(ms % chrono::seconds(1));
cout << "raw: " << hh << "::" << mm << "::"
<< ss << "::" << msec << endl;
cout << " " << setfill(’0’) << setw(2) << hh.count() << "::"
<< setw(2) << mm.count() << "::"
<< setw(2) << ss.count() << "::"
<< setw(3) << msec.count() << endl;
$ ./a.out
raw: [2 of 3600/1]::[0 of 60/1]::[55 of 1/1]::[42 of 1/1000]
02::00::55::042
Clock
=====
Defines an epoch and a tick period.
e.g. milliseconds since UNIX epoch
or nanoseconds since the start of the program
now() - the current time.
typedef ... clock::duration
typedef ... clock::rep == clock::duration::rep
typedef ... clock::period == clock::duration::period
typedef ... clock::time_point
bool clock::is_steady
time_point now();
The standard provides 3 clocks:
system_clock
------------
static std::time_t to_time_t( const time_point& t );
static std::chrono::system_clock::time_point from_time_t( std::time_t t );
steady_clock
------------
gives garanties that it never gets adjusted: advance at a steady rate
g++ 4.7 elott std::chrono::monotonic_clock
high_resolution_clock
---------------------
represents with the shortest tick period on the system
#include <chrono>
#include <iostream>
#include <iomanip>
template <typename C>
void printClockData ()
{
using namespace std;
std::cout << "- precision: ";
typedef typename C::period P;
if (std::ratio_less_equal<P,milli>::value)
{
typedef typename ratio_multiply<P,kilo>::type TT;
std::cout<<fixed<<double(TT::num)/TT::den<< " milliseconds" <<std::endl;
}
else
{
std::cout << fixed << double(P::num)/P::den << " seconds" << std::endl;
}
std::cout << "- is_steady: " << boolalpha << C::is_steady << std::endl;
}
int main()
{
std::cout << "system_clock: " << std::endl;
printClockData<std::chrono::system_clock>();
std::cout << "\nhigh_resolution_clock: " << std::endl;
printClockData<std::chrono::high_resolution_clock>();
std::cout << "\nsteady_clock: " << std::endl;
printClockData<std::chrono::steady_clock>();
}
$ ./a.out
system_clock:
- precision: 0.000001 milliseconds
- is_steady: false
high_resolution_clock:
- precision: 0.000001 milliseconds
- is_steady: false
steady_clock:
- precision: 0.000001 milliseconds
- is_steady: true
Timepoint
=========
Specific timepoint in time: positive or negative duration to a given clock.
namespace std {
namespace chrono {
template <typename Clock, typename Duration = typename Clock::duration>
class time_point;
}
}
- default constructor creates epoch
- current time is given by now()
- minimum timepoint min()
- maximum timepoint max()
#include <chrono>
#include <ctime>
#include <string>
#include <iostream>
std::string asString (const std::chrono::system_clock::time_point& tp)
{
std::time_t t = std::chrono::system_clock::to_time_t(tp);
std::string ts = std::ctime(&t);
ts.resize(ts.size()-1);
return ts;
}
int main()
{
std::chrono::system_clock::time_point tp;
std::cout << "epoch: " << asString(tp) << std::endl;
tp = std::chrono::system_clock::now();
std::cout << "now: " << asString(tp) << std::endl;
tp = std::chrono::system_clock::time_point::min();
std::cout << "min: " << asString(tp) << std::endl;
tp = std::chrono::system_clock::time_point::max();
std::cout << "max: " << asString(tp) << std::endl;
}
$ ./a.out
epoch: Thu Jan 1 01:00:00 1970
now: Sun Oct 16 19:19:51 2016
min: Tue Sep 21 01:29:04 1677
max: Sat Apr 12 01:47:16 2262
Blocking on timers
==================
std::this_thread::sleep_for(std::chrono::duration)
std::this_thread::sleep_until(std::chrono::time_point)
#include <iostream>
#include <chrono>
#include <thread>
int main()
{
using namespace std::chrono_literals;
std::cout << "Hello waiter" << std::endl;
auto start = std::chrono::high_resolution_clock::now();
std::this_thread::sleep_for(2s);
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed = end-start;
std::cout << "Waited " << elapsed.count() << " ms\n";
}
High resolution profiling
=========================
Based on https:
#include <iostream>
#include <chrono>
using namespace std;
int main()
{
cout << chrono::high_resolution_clock::period::den << endl;
auto start_time = chrono::high_resolution_clock::now();
int temp;
for (int i = 0; i< 242000000; i++)
temp+=temp;
auto end_time = chrono::high_resolution_clock::now();
cout << chrono::duration_cast<chrono::seconds>(end_time - start_time)
.count() << ":";
cout << chrono::duration_cast<chrono::microseconds>(end_time - start_time)
.count() << ":";
return 0;
}
./a.out
1000000000
0:605527: