CHRONO LIBRARY


Based on Nikolai Josuttis
http://www.informit.com/articles/article.aspx?p=1881386&seqNum=2


<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   //gcd-re normalizalva
{
  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   // split to different duration types
d1 == d2
d1 != d2
d1 < d2
++d  (increment by 1 tick)
...


chrono::seconds       d1(42);   // 42 seconds
chrono::milliseconds  d2(10);   // 10 milliseconds

d1 - d2  // a duration of 41,990 ticks of unit type milliseconds.


std::chrono::seconds twentySeconds(20);  // 20 seconds
std::chrono::hours   aDay(24);           // 24 hours

std::chrono::milliseconds ms;            // 0 milliseconds
ms += twentySeconds + aDay;              // 86,400,000 milliseconds
--ms;                                    // 86,399,999 milliseconds
ms *= 2;                                 // 172,839,998 milliseconds
std::cout << ms.count() << " ms" << std::endl;
std::cout << std::chrono::nanoseconds(ms).count() << " ns" << std::endl;

172839998 ms
172839998000000 ns

 d.count()                     // ticks
 D d2 = duration_cast<D>(d);
 duration::zero()
 typedef ... duration::rep
 typedef ... duration::period


// example 1
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;

// result:
[42 of 1/1000]


// example 2
std::chrono::duration<double,std::ratio<60>> halfMin(0.5);
std::chrono::seconds s1 = halfMin;   // ERROR, integral duration type
std::chrono::seconds s2 =
      std::chrono::duration_cast<std::chrono::seconds>(halfMin);  // OK


// example 3
using namespace std;
using namespace std::chrono;

milliseconds ms(7255042);

// split into hours, minutes, seconds, and milliseconds
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));

// and print durations and values:
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;
//result:
$ ./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  // the usual op system time clock, "calendar time"
------------

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

// Sample

#include <chrono>
#include <iostream>
#include <iomanip>

template <typename C>
void printClockData ()
{
    using namespace std;

    std::cout << "- precision: ";
    // if time unit is less or equal one millisecond
    typedef typename C::period P;// type of time unit
    if (std::ratio_less_equal<P,milli>::value)
    {
       // convert to and print as milliseconds
       typedef typename ratio_multiply<P,kilo>::type TT;
       std::cout<<fixed<<double(TT::num)/TT::den<< " milliseconds" <<std::endl;
    }
    else
    {
        // print as seconds
        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()


// example

#include <chrono>
#include <ctime>
#include <string>
#include <iostream>

std::string asString (const std::chrono::system_clock::time_point& tp)
{
     // convert to system time:
     std::time_t t = std::chrono::system_clock::to_time_t(tp);
     std::string ts = std::ctime(&t);// convert to calendar time, use local
     ts.resize(ts.size()-1);         // skip trailing newline
     return ts;
}

// portable only when using system_clock, 
//  - other clocks not necessary have to_time_t
//  - other clocks may have different epoch

int main()
{
     // print the epoch of this system clock:
     std::chrono::system_clock::time_point tp;
     std::cout << "epoch: " << asString(tp) << std::endl;

     // print current time:
     tp = std::chrono::system_clock::now();
     std::cout << "now:   " << asString(tp) << std::endl;

     // print minimum time of this system clock:
     tp = std::chrono::system_clock::time_point::min();
     std::cout << "min:   " << asString(tp) << std::endl;

     // print maximum time of this system clock:
     tp = std::chrono::system_clock::time_point::max();
     std::cout << "max:   " << asString(tp) << std::endl;
}

// result:
$ ./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);
    // std::this_thread::sleep_until(std::chrono::system_clock::now()
    //                                      + std::chrono::seconds(2));
    // daylight time switching ???
    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://www.guyrutenberg.com/2013/01/27/using-stdchronohigh_resolution_clock-example/


#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: