timer-----计算程序时间

来源:互联网 发布:linux 备份 编辑:程序博客网 时间:2024/06/07 18:26

一般的计时器基本上都是有问题的,无论用 clock() /QueryPerformanceCounter 都是有问题的,因为统计的都是 wall-time.

时间定义如下:

* Real(wall) 是时钟时间-程序从开始至结束的总时间。他包括期间其他进程所占用的时间片和进程被阻塞的时间(如IO等待的时间)* User 被测试程序在用户模式下所花的CPU时间。他是进程执行的正真的CPU时间。其他进程调度的时间片以及阻塞(如IO)的时间不包含在内。* Sys 是进程在内核中所花费的CPU时间。他表示进程在内核调用中所花的CPU时间,而程序的库调用仍然运行在用户空间下。User+Sys表示程序所执行的CPU时间(不包括IO以及其他进程的CPU时间).

真正的统计时间,我想应该是 User+Sys的时间才是真实的。如果程序很忙碌,根本就分配不了多少时间片给用户程序。

boost库提供了很多2种计时器: 基于C-API  的 clock的简单计时器和基于系统API-GetProcessTimes的计时器。

这是底层代码实现:

  void get_cpu_times(boost::timer::cpu_times& current)  {    boost::chrono::duration<boost::int64_t, boost::nano>      x (boost::chrono::high_resolution_clock::now().time_since_epoch());    current.wall = x.count();# if defined(BOOST_WINDOWS_API)    FILETIME creation, exit;    if (::GetProcessTimes(::GetCurrentProcess(), &creation, &exit,            (LPFILETIME)¤t.system, (LPFILETIME)¤t.user))    {      current.user   *= 100;  // Windows uses 100 nanosecond ticks      current.system *= 100;    }    else    {      current.system = current.user = boost::timer::nanosecond_type(-1);    }# else    tms tm;    clock_t c = ::times(&tm);    if (c == static_cast<clock_t>(-1)) // error    {      current.system = current.user = boost::timer::nanosecond_type(-1);    }    else    {      current.system = boost::timer::nanosecond_type(tm.tms_stime + tm.tms_cstime);      current.user = boost::timer::nanosecond_type(tm.tms_utime + tm.tms_cutime);      boost::int_least64_t factor;      if ((factor = tick_factor()) != -1)      {        current.user *= factor;        current.system *= factor;      }      else      {        current.user = current.system = boost::timer::nanosecond_type(-1);      }    }# endif  }

如果遇到链接 libboost_timer-vc140-mt-gd-1_65.lib(cpu_timer.obj)失败 ,需要包含chron库。

简单的API

#include <boost/progress.hpp>#include <boost/timer.hpp>提供了boost::timer boost::progress_timerboost::progress_display

timer提供简单接口, restart/elapsed,计时长度24天

progress_timer提供了 析构打印

progress_display 提供了 进度打印



最重要的 timer:

#include <boost/timer/timer.hpp>class cpu_timer通用timer//信息接口bool          is_stopped() constcpu_times     elapsed() conststd::string   format(short places, const std::string& format) conststd::string   format(short places = default_places) const//动作void          start() ;void          stop() ;void          resume() ;boost::timer::auto_cpu_timer 析构打印

当然还有格式化操作:

格式化
%w times.wall
%u times.user
%s times.system
%t times.user + times.system
%p The percentage of times.wall represented by times.user + times.system
std::string format(const cpu_times& times, short places, const std::string& format);
std::string format(const cpu_times& times, short places = default_places);


测试如下

JOB_DEFINE(boost_timer ,cpu_timer){boost::timer::cpu_timer  cpt;for (long i = 0; i < 1000; ++i){std::sqrt(123.456L); // burn some time}PS(cpt.format());PS(cpt.format(boost::timer::default_places , "W:%w U:%u S:%s U+S:%t P:%p"));PS(cpt.format(8 , "W:%w U:%u S:%s U+S:%t P:%p"));}

测试结果:

=====<boost_timer_cpu_timer>begin[cpt.format()]:[ 0.000126s wall, 0.000000s user + 0.000000s system = 0.000000s CPU (n/a%)][cpt.format(boost::timer::default_places , "W:%w U:%u S:%s U+S:%t P:%p")]:[W:0.024661 U:0.000000 S:0.000000 U+S:0.000000 P:n/a][cpt.format(8 , "W:%w U:%u S:%s U+S:%t P:%p")]:[W:0.03628942 U:0.00000000 S:0.00000000 U+S:0.00000000 P:n/a]=====<boost_timer_cpu_timer>end [State:OK] [Times:0.045s]

有意思的是 默认 format,添加了换行符号。

然后测试一下 clock耗时和 cpu_timer耗时.

我写的  JOB_DEFINE 库 是默认使用 clock计时的,因为要跨平台和最小化依赖。

JOB_DEFINE(boost_timer , auto_cpu_timer){boost::timer::auto_cpu_timer t1;for (long i = 0; i < 100000000; ++i)std::sqrt(123.456L); // burn some time}



明显 clock计时 不够精确, 以后就用 boost.timer.cpu_timer吧。




















原创粉丝点击