boost:cpu_timer ﹏ヽ暗。殇╰゛Y 2023-01-22 04:59 24阅读 0赞 # 概述 # * 在[这里][Link 1]我们初步学习了timer库,现在我们来看它们的高精度版本cpu\_timer * cpu\_timer使用了chrono库的高精度时钟high\_resolution\_clock,不仅能够度量进程使用的实际时间,还能够度量CPU时间,它支持最高到微秒精度的计时,而且使用起来同样方便,是旧版本timer的很好替代品 * cpu\_timer库需要system库和chrone库的支持;将-lboost\_timer添加到库;它位于名字空间boost::timer,需要包含头文件`<boost/timer/timer>` #include <boost/timer/timer.hpp> using namespace boost::timer; ## 时间类型 ## typedef boost::int_least64_t nanosecond_type; //计时用的ns类型 struct cpu_times //cpu时间类型 { nanosecond_type wall; //挂钟(日历时间) nanosecond_type user; //用户CPU(进程)时间 nanosecond_type system; //系统CPU(进程)时间 void clear() { wall = user = system = 0LL; } //清零 }; * cpu\_timer库以nanosecond\_type作为计时单位,但是因为系统限制它不会达到ns级别的精确度。实际情况wall的精度大约是us(1000ns),CPU时间的精度大约是10-15ms(1000\*1000ns) * cpu\_timers整合里三个计算机常用的时间度量 <table> <thead> <tr> <th>度量</th> <th>说明</th> </tr> </thead> <tbody> <tr> <td>wall</td> <td>挂钟(日历时间),进程运行的实际时间</td> </tr> <tr> <td>user</td> <td>用户CPU(进程)时间,进程执行用户指令使用的CPU时间</td> </tr> <tr> <td>system</td> <td>系统CPU(进程)时间,进程执行系统内核调用使用的CPU时间</td> </tr> </tbody> </table> * cpu\_timers是一个POD类型,只有一个简单的clear()成员函数用于时间清理 ## cpu\_timer ## class BOOST_TIMER_DECL cpu_timer { public: cpu_timer() { start(); } //构造函数,启用计时器 bool is_stopped() const ; // 计时器是否停止 cpu_times elapsed() const; // 计时器启动后流逝的时间 //格式化输出 std::string format(short places, const std::string& format) const; std::string format(short places = default_places) const; // actions void start(); // 启动计时器 void stop(); // 暂停计时器 void resume(); // 恢复计时器计时 private: cpu_times m_times; //计时成员变量 bool m_is_stopped; //是否停止计时器 }; * cpu\_timer的实现原理与timer类似,只是内部改用chrono库的高精度时钟来获得时间计量,并且时间计量也不是一个简单的std::clock\_t,而是改成了含有三个数值的类型cpu\_times * cpu\_timer的构造函数调用start()记录当前时间作为计时起点,之后就可以用elapsed()来获得启动后流逝的挂钟/用户CPU/系统CPU时间。计时过程中我们可以用stop()暂停计时器,用resume()恢复计时器的运行,如果想重新启动计时器则需要调用start() 【timer需要使用的是restart()】 * cpu\_timers没有流输出功能,但是提供了格式化函数format(),可以把elapsed()的结构转换为一个可读的字符串:`Xs wall, Ys user + Zs system = Cs CPU (P%)`,表示进程运行了X秒的挂钟时间,Y秒的用户CPU时间,Z秒的系统CPU时间,合计C秒的CPU时间,总CPU时间占挂钟时间的百分比是P(当然,字符串的格式是可以自定义的) #include <iostream> #include <boost/timer/timer.hpp> #include <vector> using namespace boost::timer; using namespace std; #include <boost/algorithm/string.hpp> int main() { vector<string> v(10, "nanodo"); cpu_timer t; //构造函数,启动计时器 assert(!t.is_stopped()); //计时器是否停止 for(int i = 0; i < 10000; ++i){ boost::join(v, "-"); } 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(); //格式化输出 } ![在这里插入图片描述][20210517175455334.png] 从上面我们可以知道,进程总共花费了0.012s时间,其中用户CPU时间约0.01s,系统CPU时间为0(即没有发生系统调用),CPU时间占总运行时间78.0% ## auto\_cpu\_timer ## auto\_cpu\_timer是一个类似`progress_timer`的自动计时器,它继承自cpu\_timer: class BOOST_TIMER_DECL auto_cpu_timer : public cpu_timer { public: explicit auto_cpu_timer(short places = default_places); auto_cpu_timer(short places, const std::string& format); explicit auto_cpu_timer(const std::string& format); auto_cpu_timer(std::ostream& os, short places,const std::string& format) explicit auto_cpu_timer(std::ostream& os, short places = default_places); auto_cpu_timer(std::ostream& os, const std::string& format) ~auto_cpu_timer(); std::ostream& ostream() const { return *m_os; } short places() const { return m_places; } const std::string& format_string() const { return m_format; } // actions void report(); }; * auto\_cpu\_timer 具有cpu\_timer的所有接口,同progress\_timer一样,它会在析构的时候自动输出流逝的时间,非常的简单易用,我们也可以用report()函数直接向流输出计时结果 * auto\_cpu\_timer有6个构造函数,可以用来定制计时的输出格式 { auto_cpu_timer t; sleep(1); } ![在这里插入图片描述][20210517180723270.png] ## 定制输出格式 ## cpu\_timer库的format函数使用两个参数来定制计时结果的时间类型cpu\_timers的格式: * 短整型places用于指定输出值的小数点后精确度,默认值是6us,最多可以是9ns(但是因为计时精度的限制通常是没有意义的) * 字符串参数format用于指定输出的格式 const string fmt("%w 秒, %u 秒 + %s 秒 = %t 秒, 百分比是%p"); auto_cpu_timer t(3, fmt); // 指定精度和格式 > * %w : 挂钟时间,即cpu\_times.wall值 > * %u:用户CPU时间,即cpu\_times.user值 > * %s:系统CPU时间,即cpu\_times.system值 > * %t:总计CPU时间,即cpu\_times.user + cpu\_timers.system > * %p:总计CPU时间占挂钟时间的百分比 cpu\_timer库里面还有两个格式化函数,用来把cpu\_times类型格式化为字符串,被cpu\_timer和auto\_cpu\_timer调用: BOOST_TIMER_DECL std::string format(const cpu_times& times, short places, const std::string& format); BOOST_TIMER_DECL std::string format(const cpu_times& times, short places = default_places); 示例如下: const nanosecond_type ms = 1000 * 1000; cpu_times ct = { 2000 * ms, 1000 * ms, 100 * ms}; cout << format(ct, 7); ![在这里插入图片描述][20210518103818625.png] 如果CPU时间值太小,小于cpu\_timer库的度量精度,那么百分比就会显式为n/a(not available) cpu_times ct = { 2000, 1000 , 100 }; cout << format(ct, 7); //使用默认格式输出 ![在这里插入图片描述][20210518103947627.png] [Link 1]: https://blog.csdn.net/zhizhengguan/article/details/109093956 [20210517175455334.png]: /images/20221020/1b3fa11877114a59a7aeb604631314f3.png [20210517180723270.png]: /images/20221020/999b3f97acab45a78f1605131bbe515e.png [20210518103818625.png]: /images/20221020/6555b8a8fd47402880e90c09b9f9236e.png [20210518103947627.png]: /images/20221020/9d516ee08786463094d6c0991c294fb3.png
还没有评论,来说两句吧...