c++11 boost - chrono、cpu_timer

2018-07-13 09:58:49

chrono 库里很多事件的概念和 date_time 库类似,但它更侧重于表达计算机世界里的时间。

duration 类表示时间长度,侧重于编译期的时间单位表示,更接近ratio。

// Copyright (c) 2015
// Author: Chrono Law
#include <iostream>
using namespace std;

#define BOOST_ERROR_CODE_HEADER_ONLY  //无需编译即可使用 system 库
#define BOOST_CHRONO_HEADER_ONLY      //无需编译即可使用 chrono 库
#define BOOST_CHRONO_EXTENSIONS       //使用扩展功能
#include <boost/chrono.hpp>
using namespace boost;
using namespace boost::chrono;

//////////////////////////////////////////
typedef duration<long,   ratio<30>> half_min;
typedef duration<int,    ratio<60*15>> quater;
typedef duration<double, ratio<3600*24>> day;

//typedef duration<int,60*60> my_hour;  //不能直接用整数
//typedef duration<int,ratio<-10, 1000>> my_ms;  //不能使用负数
void case1()
{
    seconds s(10);
    minutes m(5);
    hours   h(1);
    milliseconds ms(100);

    assert(s.count() == 10);
    assert(ms.count() == 100);

    //可以执行运算
    s *= 3;
    s += seconds(30);
    s = s - seconds(20);
    assert(s < seconds(50));
    cout << s << endl << endl;

}

void case2()
{
    seconds s(10);
    minutes m(5);

    s += m;
    cout << s << endl;

    //m+= s;

    {
        seconds s(10);
        typedef duration<double, ratio<60>> my_min;
        my_min m(5);
        m += s;  //混合运算,分+秒
        cout << m << endl;
    }

    {
        seconds s(40);  //40秒
        auto m = duration_cast<minutes>(s);
        cout << m << endl; //0分

        seconds s2(301);
        cout << duration_cast<minutes>(s2) << endl;  //5分
    }

    {
        seconds s(3600 + 50);
        cout << floor<minutes>(s) << endl;  //上上界
        cout << ceil<minutes>(s) << endl;   //下界
        cout << round<minutes>(s) << endl;  //四舍五入
        cout << round<hours>(s) << endl << endl;
    }
}

//时钟
template<typename T>
using clock_desc = clock_string<T, char>;

void case3()
{
    cout << clock_desc<system_clock>::name() << endl;
    cout << clock_desc<system_clock>::since() << endl;

    cout << clock_desc<steady_clock>::name() << endl;
    cout << clock_desc<steady_clock>::since() << endl;

    cout << clock_desc<process_real_cpu_clock>::name() << endl;
    cout << clock_desc<process_real_cpu_clock>::since() << endl << endl;
}

void case4()
{
    auto tp1 = system_clock::now();
    cout << tp1 << endl;

    auto d = tp1.time_since_epoch();
    cout << duration_cast<hours>(d) << endl;
    cout << duration_cast<day>(d) << endl;

    auto tp2 = tp1 +minutes(1);
    cout << tp2 << endl;

    {
        auto tp = steady_clock::now();
        cout << tp << endl;

        auto d = tp.time_since_epoch();
        cout << round<minutes>(d) << endl;
        cout << round<hours>(d) << endl << endl;
    }
}

//c++11定义字面值
hours operator"" _h(unsigned long long n)
{
    return hours(n);
}

seconds operator"" _s(unsigned long long n)
{
    return seconds(n);
}

milliseconds operator"" _ms(unsigned long long n)
{
    return milliseconds(n);
}
void case5()
{
    auto h = 5_h;
    auto s = 45_s;
    auto ms = 200_ms;

    cout << h << " " << s << " " << ms << " " << endl;
}
//转换成time_t
void case6()
{
    auto tp = system_clock::now();
    auto t = system_clock::to_time_t(tp);

    cout << std::ctime(&t) << endl;
}

//计算cpu时间
class steady_timer final
{
private:
    typedef boost::chrono::steady_clock clock_type;

    //typedef clock_type::duration duration_type;
    typedef clock_type::time_point time_point_type;
    typedef boost::chrono::microseconds duration_type;

    time_point_type m_start = clock_type::now();
public:
    steady_timer() = default;
    ~steady_timer() = default;
public:
    void restart()
    {
        m_start = clock_type::now();
    }

    duration_type elapsed() const
    {
        return round<duration_type>(
                clock_type::now() - m_start);
    }
};

int main()
{
    steady_timer t;

    case1();
    case2();
    case3();
    case4();
    case5();
    case6();

    cout << t.elapsed() << endl;
}
[root@192 c++]# g++ -std=c++11 main.cpp 
[root@192 c++]# ./a.out 
40 seconds

310 seconds
5.16667 minutes
0 minutes
5 minutes
60 minutes
61 minutes
61 minutes
1 hour

system_clock
 since Jan 1, 1970
steady_clock
 since boot
process_real_clock
 since process start-up

1531445057411973446 nanoseconds since Jan 1, 1970
425401 hours
17725.1 [86400/1]seconds
1531445117411973446 nanoseconds since Jan 1, 1970
285141513948044 nanoseconds since boot
4752 minutes
79 hours

5 hours 45 seconds 200 milliseconds 
Fri Jul 13 09:24:17 2018

446 microseconds


cpu_timer 库是用来统计程序运行的cpu时间,比 timer 精度更高。

// Copyright (c) 2015
// Author: Chrono Law
#include <iostream>
using namespace std;

#include <boost/algorithm/string.hpp>
#include <boost/timer/timer.hpp>
using namespace boost::timer;

void case1()
{
    vector<string> v(10, "monado");

    cpu_timer t;
    assert(!t.is_stopped());

    for (int i = 0;i < 1000000; ++i)
    {
        boost::join(v, "-");
    }//end for

    t.stop();
    assert(t.is_stopped());

    cout << "pause for a while..." << endl;
    cout << "we can do something..." << endl;

    t.resume();
    assert(!t.is_stopped());

    for(string& x : v)
    {   x +=x; }
	
    cout << t.format();
    cout << format(t.elapsed(),4) << endl;
    
    cpu_times tt = t.elapsed();
    cout << tt.wall << " ns" << endl;  //时钟时间-纳秒
    cout << tt.user << " ns" << endl;  //用户cpu时间-纳秒
    cout << tt.system << " ns" << endl << endl;  //系统cpu时间-纳秒
    
}

void case2()
{
    const nanosecond_type ms = 1000 * 1000;

    cpu_times ct = {2000 *ms, 1000*ms, 100*ms};
    cout << format(ct, 7);
}

void case3()
{
    cpu_times ct = {2000, 1000, 100 };  //指定初始时间
    
    cout << format(ct, 3);

}

//auto_cpu_timer 在程序结束时自动输出
void case4()
{
    const string fmt("时间:%ws 用户CPU:%us 系统CPU:%ss 总CPU:%ts 百分比:%p%\n");
    auto_cpu_timer t(3,fmt);  //指定精度和格式
    
    sleep(2);
    
    for (int i = 0;i < 1000000; ++i)
    {
        int a = i;
    }
	
}

int main()
{
    case1();
    case2();
    case3();
    case4();
}

注意编译的时候链接 libboost_timer.so 动态库,否则会报如下错误。

main.cpp:(.text+0x105): undefined reference to `boost::timer::cpu_timer::stop()'
main.cpp:(.text+0x178): undefined reference to `boost::timer::cpu_timer::resume()'
main.cpp:(.text+0x277): undefined reference to `boost::timer::cpu_timer::elapsed() const'
main.cpp:(.text+0x28f): undefined reference to `boost::timer::format(boost::timer::cpu_times const&, short)'
main.cpp:(.text+0x2d2): undefined reference to `boost::timer::cpu_timer::elapsed() const'
main.cpp:(.text+0x574): undefined reference to `boost::timer::auto_cpu_timer::~auto_cpu_timer()'
main.cpp:(.text+0x5ab): undefined reference to `boost::timer::auto_cpu_timer::~auto_cpu_timer()'
[root@192 c++]# g++ -std=c++11 main.cpp -lboost_timer -L /usr/local/lib/boost_1_65_1/
[root@192 c++]# ./a.out 
pause for a while...
we can do something...
 1.658478s wall, 1.650000s user + 0.000000s system = 1.650000s CPU (99.5%)
 1.6585s wall, 1.6500s user + 0.0000s system = 1.6500s CPU (99.5%)

1658532600 ns
1650000000 ns
0 ns
 2.0000000s wall, 1.0000000s user + 0.1000000s system = 1.1000000s CPU (55.0%)
 0.000s wall, 0.000s user + 0.000s system = 0.000s CPU (n/a%)
时间:2.009s 用户CPU:0.010s 系统CPU:0.000s 总CPU:0.010s 百分比:0.5%


 备注

1.编译器版本gcc4.8.5,运行环境centos7 64位
2.本文只做简单记录用,详细用法请参考 Boost Library,或者是罗剑锋的 boost程序库完全开发指南 书本
3..原文地址http://www.freecls.com/a/2712/ae


©著作权归作者所有
收藏
推荐阅读
简介
天降大任于斯人也,必先苦其心志。