c++11 chrono全面解析(高精度时钟,可达纳秒级别)

1.精度:


时钟节拍(时间精度):

template <intmax_t N, intmax_t D = 1> class ratio;

其中N表示分子,D表示分母,默认用秒表示的时间单位。
N对应于其成员num,D对应于其成员den

常用的单位:

ratio<60, 1>                    minute

ratio<1, 1>                      second

ratio<1, 1000>               millisecond

...

ratio主要是是为后面将要讲解的时间段,时间点等提供精度(单位)

#include<iostream>
#include<chrono>
using namespace std;
int main()
{
	cout << "millisecond : ";
	cout << std::chrono::milliseconds::period::num << "/" << std::chrono::milliseconds::period::den << "s" <<endl;
	system("pause");
	return 0;
}

 

2.时间段:

template <class Rep, class Period = ratio<1> >
class duration;
std::chrono::duration 表示一段时间,比如两个小时,12.88秒,半个时辰,一炷香的时间等等

Rep表示一种数值类型,用来表示Period的数量,比如int float double。
Period是ratio类型,用来表示上面所说的单位精度,比如second milisecond。
chrono中宏定义了许多特例化了的duration:
就是常见的hours,miniutes,seconds,milliseconds等,使用std::chrono::milliseconds直接使用。

(1)成员函数count()返回单位时间的数量。

#include <iostream>
#include <chrono>
int main()
{
	std::chrono::milliseconds mscond(1000); // 1 second
	std::cout << mscond.count() << " milliseconds.\n";
 
	std::cout << mscond.count() * std::chrono::milliseconds::period::num / std::chrono::milliseconds::period::den;
	std::cout << " seconds.\n";
	system("pause");
	return 0;
}

 

3.时间点:

template <class Clock, class Duration = typename Clock::duration>
  class time_point;
std::chrono::time_point 表示一个具体时间,如上个世纪80年代、今天下午3点、火车出发时间等,只要它能用计算机时钟表示。

第一个模板参数Clock用来指定所要使用的时钟(标准库中有三种时钟,system_clock,steady_clock和high_resolution_clock。见4时钟详解),第二个模板函数参数用来表示时间的计量单位(特化的std::chrono::duration<> )

时间点都有一个时间戳,即时间原点。chrono库中采用的是Unix的时间戳1970年1月1日 00:00。所以time_point也就是距离时间戳(epoch)的时间长度(duration)。

(1)构造函数:


(1)  time_point();           //默认构造函数,时间戳作为其值
(2)  template <class Duration2>
time_point (const time_point<clock,Duration2>& tp);  //拷贝构造函数
(3)  explicit time_point (const duration& dtn);      //使用duration构造,就是距离时间戳的时间长度

(2)时间点有个重要的函数:duration time_since_epoch()  (用于获取当前时间点距离时间戳的时间长度)
即经常用来得到当前时间点到1970年1月1日00:00的时间距离、该函数返回的duration的精度和构造time_point的时钟(Clock)有关(见4时钟详解)。

#include <iostream>
#include <chrono>
#include <ctime>
using namespace std;
int main()
{
	//距离时间戳2两秒
	chrono::time_point<chrono::system_clock, chrono::seconds> tp(chrono::seconds(2));
	cout << "to epoch : " <<tp.time_since_epoch().count() << "s" <<endl;
	//转化为ctime,打印输出时间点
	time_t tt = chrono::system_clock::to_time_t(tp);
	char a[50];
	ctime_s(a, sizeof(a), &tt);
	cout << a;
	system("pause");
	return 0;
}

4.时钟:(代表当前系统的时间)

chrono中有三种时钟:system_clock,steady_clock和high_resolution_clock。每一个clock类中都有确定的time_point, duration, Rep, Period类型。

system_clock是不稳定的。因为时钟是可调的,即这种是完全自动适应本地账户的调节。这种调节可能造成的是,首次调用now()返回的时间要早于上次调用now()所返回的时间,这就违反了节拍频率的均匀分布。稳定闹钟对于超时的计算很重要,所以C++标准库提供一个稳定时钟 std::chrono::steady_clock。std::chrono::high_resolution_clock 是标准库中提供的具有最小节拍周期(因此具有最高的精度的时钟)。

上文所说time_since_epoch(),以及将要介绍的now()函数的返回值都依赖于时钟的精度,测试时钟的精度的一种方法就是:

#include <iostream>
#include <chrono>
using namespace std;
int main()
{
	cout << "system clock          : ";
	cout << chrono::system_clock::period::num << "/" << chrono::system_clock::period::den << "s" << endl;
	cout << "steady clock          : ";
	cout << chrono::steady_clock::period::num << "/" << chrono::steady_clock::period::den << "s" << endl;
	cout << "high resolution clock : ";
	cout << chrono::high_resolution_clock::period::num << "/" << chrono::high_resolution_clock::period::den << "s" << endl;
	system("pause");
	return 0;
}

 

综合实例:

#ifndef _CELLTimestamp_hpp_
#define _CELLTimestamp_hpp_

//#include <windows.h>
#include<chrono>
using namespace std::chrono;
class CELLTimestamp
{
public:
    CELLTimestamp()
    {
        //QueryPerformanceFrequency(&_frequency);
        //QueryPerformanceCounter(&_startCount);
		update();
    }
    ~CELLTimestamp()
    {}

    void  update()
    {
        //QueryPerformanceCounter(&_startCount);
		_begin = high_resolution_clock::now();
    }
    /**
    *   获取当前秒
    */
    double getElapsedSecond()
    {
        return  getElapsedTimeInMicroSec() * 0.000001;
    }
    /**
    *   获取毫秒
    */
    double getElapsedTimeInMilliSec()
    {
        return this->getElapsedTimeInMicroSec() * 0.001;
    }
    /**
    *   获取微妙
    */
    long long getElapsedTimeInMicroSec()
    {
		/*
        LARGE_INTEGER endCount;
        QueryPerformanceCounter(&endCount);

        double  startTimeInMicroSec =   _startCount.QuadPart * (1000000.0 / _frequency.QuadPart);
        double  endTimeInMicroSec   =   endCount.QuadPart * (1000000.0 / _frequency.QuadPart);

        return  endTimeInMicroSec - startTimeInMicroSec;
		*/
		
		return duration_cast<microseconds>(high_resolution_clock::now() - _begin).count();
    }
protected:
    //LARGE_INTEGER   _frequency;
    //LARGE_INTEGER   _startCount;
	time_point<high_resolution_clock> _begin;
};

#endif // !_CELLTimestamp_hpp_

猜你喜欢

转载自blog.csdn.net/qq_33263769/article/details/88988461