|  | Timer Library CPU Timers | 
| Timer Home CPU timers Original timers | 
Knowing how long a program takes to execute is useful in both test and production environments. It may also be helpful if such timing information is broken down into wall-clock time, CPU time spent by the user, and CPU time spent by the operating system servicing user requests.
Class cpu_timer measures 
wall-clock time, user CPU process time, and system CPU process time.  Class 
auto_cpu_timer is a refinement of
cpu_timer that automatically reports the elapsed times when an 
auto_cpu_timer object is destroyed.
auto_cpu_timerThe simplest and most common use is to add the two lines high-lighted below 
to a scope you want to time. See 
auto_cpu_timer_example.cpp 
for the source code. 
#include <boost/timer/timer.hpp> #include <cmath> int main() { boost::timer::auto_cpu_timer t; for (long i = 0; i < 100000000; ++i) std::sqrt(123.456L); // burn some time return 0; }
When the auto_cpu_timer object is created, it starts timing. When 
it is destroyed at the end of the scope, its destructor stops the timer and 
displays timing information on the default output stream, std::cout.
The output of this program, run with a debug build on a circa 2006 desktop processor:
    5.713010s wall, 5.709637s user + 0.000000s system = 
5.709637s CPU (99.9%)
In other words, this program ran in  5.713010 seconds as would be measured by a 
clock on the wall, the operating system charged it for  5.709637 seconds of user CPU 
time and 0 seconds of system CPU time, the total of these two was  5.709637, and that 
represented  99.9 percent of the wall clock time.
The output stream, number of decimal places reported, and reporting format 
can be controlled by auto_cpu_timer constructor arguments. Here is 
what the output from the above program would look like for several different 
sets of constructor arguments:
| Constructor | Resulting Output | 
| t | 5.713010s wall, 5.709637s user + 0.000000s system = 5.709637s 
    CPU (99.9%) | 
| t(std::cerr, 2) | 5.71s wall, 5.70s user + 0.00s system = 5.70s CPU (99.9%) | 
| t(1) | 5.7s wall, 5.7s user + 0.0s system = 5.7s CPU (99.9%) | 
| t(3, "%w seconds\n") | 5.713 seconds | 
| t("%t sec CPU, %w sec real")
      | 5.709637 sec CPU, 5.713010 sec real | 
The processing of the format string is described here.
cpu_timerThe following code creates a checkpoint every 20 seconds of user CPU time:
  using boost::timer::cpu_timer;
...
nanosecond_type last_checkpoint_time = 0;
cpu_timer checkpoint_timer;  // start the timer
while (more_transactions)
{
  process_a_transaction();
  if (checkpoint_timer.elapsed().user - last_checkpoint_time > 20*1000000000LL)
  {
    ... create a checkpoint ...
    last_checkpoint_time = checkpoint_timer.elapsed().user;  
  }
}
Specifications are given in the style of the C++ standard library (C++11, 17.5.1.4 [structure.specifications]). An additional Overview element may be provided to aid understanding. Overview elements are only informative - actual semantics are given by the other detailed specification elements.
 Functions not specified as noexcept will throw 
std::bad_alloc exceptions if a memory allocation error occurs. Other 
errors are reported by time values of -1. [Note: Modern hardware and 
operating systems have robust clock subsystems, so such errors are unusual if 
even possible at all. -- end note]
The Timer library meets the same data race avoidance requirements as the C++11 standard library (17.6.5.9 [res.on.data.races]). Shared objects of Timer library types risk undefined behavior unless the user supplies a locking mechanism. See C++11, 17.6.4.10 [res.on.objects], Shared objects and the library.
<boost/timer/timer.hpp>
Synopsisnamespace boost
{
  namespace timer
  {
    class cpu_timer;       // wall-clock, user, and system timer
    class auto_cpu_timer;  // automatic report() on destruction 
    typedef boost::int_least64_t nanosecond_type;
    struct cpu_times
    {
      nanosecond_type wall;
      nanosecond_type user;
      nanosecond_type system;
      void clear() { wall = user = system = 0LL; }
    };
      
    const int           default_places = 6;
    const std::string&  default_format();
    std::string format(const cpu_times& times,
                       short places = default_places,
                       const std::string& format = default_format()); 
  } // namespace timer
} // namespace boost
nanosecond_typeThe typedef nanosecond_type provides an implementation defined type capable 
of representing nanoseconds. For POSIX and Windows systems, 
nanoseconds_type is boost::int_least64_t.
The underlying type is not based on the Boost Date-Time or Chrono library to avoid a dependency on a large library. This design choice may change at some future date.
Although nanosecond_type is capable of representing one 
nanosecond, the actual resolution of common operating system timers may be 
much lower. For wall clock time on desktop systems circa 2010, resolution is 
often no better than than one microsecond. For user and system time, typical 
resolution is 15 milliseconds on Windows and 10 milliseconds on 
POSIX.
cpu_timesStruct cpu_times packages three elapsed times:
const std::string& default_format();
Returns:
std::string(" %ws wall, %us user + %ss system = %ts CPU (%p%)\n").
std::string format(const cpu_times& times, short places = default_places, const std::string& format = default_format());
Overview: Converts the
timesargument's values to strings representing seconds to a given number of decimalplaces, and inserts them into a return string under control of theformatstring.Effects: If
placesis less than 0, it is set todefault_places. Ifplacesis more than 9, it is set to 9. if theformatargument isempty(), it is set todefault_format.Returns: A string that is a copy of
format, except that any instances of the sequences shown below are replaced by the indicated value. Times are reported in seconds, shown toplacesdecimal places. Percentage is reported to one decimal place. [Note: percentage may exceed 100% due to differences in how operating systems measure various times. --end note]
Sequence Replacement value %wtimes.wall%utimes.user%stimes.system%ttimes.user + times.system%pThe percentage of times.wallrepresented bytimes.user + times.system
cpu_timer cpu_timer objects measure wall-clock elapsed time, process elapsed 
time charged to the user, and process elapsed time charged to the system.
Current time values are 
obtained as follows: Current wall-clock time is obtained from the Boost.Chrono 
high_resolution_clock. Current user and system time values are obtained 
from the appropriate operating system API functions such as times() 
on POSIX or 
GetProcessTimes() on Windows.
cpu_timer synopsis    class cpu_timer
    {
    public:
      //  constructor, destructor
      cpu_timer() noexcept;
     ~cpu_timer() noexcept {}
      //  observers
      bool              is_stopped() const noexcept;
      cpu_times         elapsed() const noexcept;
      std::string       format(int places = default_places,
                               const std::string& format = default_format()) const;
      //  actions
      void              start() noexcept;
      const cpu_times&  stop() noexcept;
      void              resume() noexcept;
    };
cpu_timer constructor, destructorcpu_timer() noexcept;
Effects: Constructs an object of type
cpu_timer. Callsstart().
~cpu_timer() noexcept {}
Effects: None
cpu_timer 
observersbool is_stopped() const noexcept;
Returns:
trueif the most recent call to an action function was to stop(), otherwisefalse.
cpu_times elapsed() const noexcept;
Overview: If the timer is running, returns the cumulative elapsed time. If the timer is stopped, returns the cumulative elapsed time previously stored by stop().
Returns: If
is_stopped(), the stored time values. Otherwise, the difference between the current time values and the stored time values.
std::string format(int places = default_places, const std::string& format = default_format()) const;
Overview: Returns a string for the current elapsed time as formatted by the format function.
Returns:
timer::format(elapsed(), places, format).
cpu_timer 
actionsvoid start() noexcept;
Effects: Stores the current time values.
Postconditions:
!is_stopped().
cpu_times stop() noexcept;
Effects: If
!is_stopped(), stores the difference between the current time values and the time values stored by the most recent call to start() or resume().Postconditions:
is_stopped().Returns: The stored times.
void resume() noexcept;
Overview: Restarts the timer, accumulating additional elapsed time.
Effects: If is_stopped(), store the current time values less the previously stored cumulative elapsed times. Otherwise, no effect. [Note: Subtracting the previous elapsed times has the effect of accumulating additional elapsed time. --end note]
auto_cpu_timerClass auto_cpu_timer adds a report() 
function to class cpu_timer, and automatically calls report() 
on destruction.
auto_cpu_timer synopsis    class auto_cpu_timer : public cpu_timer
    {
    public:
      explicit auto_cpu_timer(short places = default_places,
                              const std::string& format = default_format());
      explicit auto_cpu_timer(const std::string& format);
      explicit auto_cpu_timer(std::ostream& os,
                              short places = default_places,
                              const std::string& format = default_format());
      auto_cpu_timer(std::ostream& os, const std::string& format);
     ~auto_cpu_timer() noexcept;
      void            report();
    private:
      std::ostream&   m_os;               // exposition only
      short           m_places;           // exposition only
      std::string     m_format;           // exposition only
    };
[Note: Constructors without a std::ostream& 
argument argument imply 
std::cout. An argument default is avoided as it would require including <iostream>, 
with its high costs, even when the standard streams are not used. --end note]
auto_cpu_timer constructorsexplicit auto_cpu_timer(short places = default_places, const std::string& format = default_format());
Effects: Constructs an object of type
auto_cpu_timer.Postconditions: As if
m_os == std::cout,,
m_places == places
m_format == format
explicit auto_cpu_timer(const std::string& format);
Effects: Constructs an object of type
auto_cpu_timer.Postconditions: As if
m_os == std::cout,,
m_places == default_places
m_format == format
explicit auto_cpu_timer(std::ostream& os, short places = default_places, const std::string& format = default_format());
Effects: Constructs an object of type
auto_cpu_timer.Postconditions: As if
m_os == os,,
m_places == places
m_format == format
auto_cpu_timer(std::ostream& os, const std::string& format);
Effects: Constructs an object of type
auto_cpu_timer.Postconditions: As if
m_os == os,,
m_places == default_places
m_format == format
auto_cpu_timer destructor~auto_cpu_timer() noexcept;
Effects: If
!is_stopped(), report(). Otherwise, no effects.[Note: Because the function is
noexcept, implementation requires a try/catch or equivalent to ensure no exception escapes. --end note]
auto_cpu_timer actionsvoid report();
Effects: As if:
m_os << timer::format(stop(), m_places, m_format); resume();[Note:
stop()is called because doing I/O while the timer is running might produce misleading results. --end note]
How accurate are these timers?
The resolution of a clock, and thus timers built on that clock, 
  is the minimum period time that can be measured. The program 
  cpu_timer_info.cpp measures 
  the resolution of cpu_timer.
| O/S | Processor | Wall-clock | CPU | ||
| Resolution | Comments | User Resolution | System Resolution | ||
| Windows 7 | Intel Core i7 860 @ 2.9 GHz | 366ns | Some variation, usually in multiples of 366ns | 15600100ns | 15600100ns | 
| Windows 7 | Intel Mobile T7200 @ 2.0 GHz | 2050ns | Much variation. Resolution degrades when processor slows, probably due to known chipset errata. | 15600100ns | 15600100ns | 
| Windows XP | Intel Atom N2800 @ 1.0 GHz | 1437ns | Some variation. | 15625000ns | 15625000ns | 
| Mac OS X Lion | Intel circa 2007 | 2100ns 2200ns | Some variation within a range. | 10000000ns | 10000000ns | 
| Ubuntu Linux 11.4 | Intel circa 2005 | 516ns | Very little variation, typically less than 5ns | 10000000ns | 10000000ns | 
Wall-clock time is subject to many outside influences, such as the impact of other processes, and may even run backwards on some systems, such as when the clock is reset such as during a daylight savings time transition.
Timings of debug builds are often significantly (I.E several times) slower than release builds, both because of the lack of compiler optimization and because libraries often contain very expensive error checks on debug builds.
Synthetic benchmark code may be optimized way by release builds. It may be necessary to inspect generated code to verify this isn't happening.
Think about what is important to your application. For a production process, the wall-clock time may be what is most important. For studying the efficiency of code, CPU time is often a much better measure.
My personal preference is to never trust timings unless they are (1) at least 100 times longer than the CPU time resolution, (2) run multiple times, and (3) run on release builds. And results that are too good to be true need to be further investigate.
Comments and suggestions came from Greg Rubino, Dave Abrahams, Vicente Botet, John Maddock, and Rob Stewart.
Rob  contributed many corrections, comments, and suggestions. In 
  particular, he suggested the resume() and format() 
  functions, resulting in improved ease-of-use for several use cases.
Last revised: 28 September, 2011
© Copyright Beman Dawes, 2006, 2011
Distributed under the Boost Software License, Version 1.0. See www.boost.org/ LICENSE_1_0.txt