2
0
mirror of https://github.com/boostorg/timer.git synced 2026-01-19 04:42:13 +00:00
[SVN r74697]
This commit is contained in:
Beman Dawes
2011-10-04 15:06:50 +00:00
parent 9e83237560
commit bc3c77d467
16 changed files with 1699 additions and 56 deletions

25
build/Jamfile.v2 Normal file
View File

@@ -0,0 +1,25 @@
# Boost Timer Library Build Jamfile
# (C) Copyright Beman Dawes 2002, 2006, 2011
# Distributed under the Boost Software License, Version 1.0.
# See www.boost.org/LICENSE_1_0.txt
# See library home page at http://www.boost.org/libs/timer
project boost/timer
: source-location ../src
: usage-requirements # pass these requirement to dependents (i.e. users)
<link>shared:<define>BOOST_TIMER_DYN_LINK=1
<link>static:<define>BOOST_TIMER_STATIC_LINK=1
;
SOURCES = auto_timers auto_timers_construction cpu_timer ;
lib boost_timer
: $(SOURCES).cpp ../../chrono/build//boost_chrono
: <link>shared:<define>BOOST_TIMER_DYN_LINK=1
<link>static:<define>BOOST_TIMER_STATIC_LINK=1
;
boost-install boost_timer ;

693
doc/cpu_timers.html Normal file
View File

@@ -0,0 +1,693 @@
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>CPU Timers</title>
<style type="text/css">
ins {background-color:#A0FFA0}
del {background-color:#FFA0A0}
body
{
font-family: sans-serif;
max-width : 8.5in;
margin: 1em;
}
</style>
</head>
<body>
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="750">
<tr>
<td width="300">
<a href="../../../index.htm">
<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="300" height="86" border="0"></a></td>
<td align="middle" width="430">
<font size="7">Timer Library<br>
CPU Timers</font></td>
</tr>
</table>
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%">
<tr>
<td><a href="index.html">Timer Home</a> &nbsp;&nbsp;
<a href="cpu_timers.html">CPU timers</a> &nbsp;&nbsp;
<a href="original_timer.html">Original timers</a> &nbsp;&nbsp;
</td>
</tr>
</table>
<h2><a name="Introduction">Introduction</a></h2>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" align="right">
<tr>
<td width="100%" bgcolor="#D7EEFF" align="center">
<i><b>Contents</b></i></td>
</tr>
<tr>
<td width="100%" bgcolor="#E8F5FF">
<a href="#Introduction">Introduction</a><br>
<a href="#Example">Using the timers</a><br>
&nbsp; <a href="#using-auto_cpu_timer">Using <code>auto_cpu_time</code>r</a><br>
&nbsp; <a href="#using-cpu_timer">Using <code>cpu_timer</code></a><br>
<a href="#Reference">Reference</a><br>
<code>&nbsp;<a href="#Synopsis">&lt;boost/timer/timer.hpp&gt;</a></code><a href="#Synopsis">
synopsis</a><br>
&nbsp; <a href="#nanosecond_type">Typedef <code>nanosecond_type</code></a><br>
&nbsp;
<a href="#Non-member-functions">Non-member functions</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <code><a href="#default_format">default_format()</a></code><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#format"><code>format()</code></a><br>
&nbsp;
<a href="#Class-cpu_timer">Class <code>cpu_timer</code></a><br>
&nbsp;&nbsp;<code>&nbsp; <a href="#cpu_timer-constructors">cpu_timer</a></code><a href="#cpu_timer-constructors">
constructors, destructor</a><br>
&nbsp;&nbsp;<code>&nbsp; <a href="#cpu_timer-observers">cpu_timer</a></code><a href="#cpu_timer-observers">
observers</a><br>
&nbsp;&nbsp;<code>&nbsp; <a href="#cpu_timer-actions">cpu_timer</a></code><a href="#cpu_timer-actions">
actions</a><br>
&nbsp; <a href="#Class-auto_cpu_timer">Class <code>auto_cpu_timer</code></a><br>
&nbsp;&nbsp;&nbsp;<code> <a href="#auto_cpu_timer-constructors">auto_cpu_timer</a></code><a href="#auto_cpu_timer-constructors"> constructors</a><br>
&nbsp;&nbsp;&nbsp;<code> <a href="#auto_cpu_timer-destructor">auto_cpu_timer</a></code><a href="#auto_cpu_timer-destructor"> destructor</a><br>
&nbsp;&nbsp;&nbsp;<code> <a href="#auto_cpu_timer-actions">auto_cpu_timer</a></code><a href="#auto_cpu_timer-actions"> actions</a><br>
<a href="#Timer-accuracy">Timer accuracy</a><br>
&nbsp; <a href="#Resolution">Resolution</a><br>
&nbsp; <a href="#Other-concerns">Other concerns</a><br>
&nbsp; <a href="#Recommendations">Recommendations</a><br>
<a href="#History">History</a><br>
<a href="#Acknowledgements">Acknowledgements</a><br>
</tr>
</table>
<p>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.</p>
<p>Class <code><a href="#Class-cpu_timer">cpu_timer</a></code> measures
wall-clock time, user CPU process time, and system CPU process time. Class <code>
<a href="#Class-auto_cpu_timer">auto_cpu_timer</a></code> is a refinement of
<code>cpu_timer</code> that automatically reports the elapsed times when an <code>
auto_cpu_timer</code> object is destroyed.</p>
<h2><a name="Setup">Setup</a></h2>
<p>Boost.Timer is implemented as a separately compiled library, so you must
install binaries in a location that can be found by your linker. If you followed
the
<a href="http://www.boost.org/doc/libs/release/more/getting_started/index.html">
Boost Getting Started</a> instructions, that's already been done.</p>
<h2><a name="Example">Using the timers</a></h2>
<h3>Using <code><a name="using-auto_cpu_timer">auto_cpu_timer</a></code></h3>
<p>The simplest and most common use is to add the two lines high-lighted below
to a scope you want to time. See <code>
<a href="../example/auto_cpu_example.cpp">auto_cpu_timer_example.cpp</a></code>
for the source code. </p>
<blockquote>
<pre><span style="background-color: #D7EEFF">#include &lt;boost/timer/</span><span style="background-color: #D7EEFF">timer.hpp</span><span style="background-color: #D7EEFF">&gt;</span>
#include &lt;cmath&gt;
int main()
{
<span style="background-color: #D7EEFF">boost::timer::auto_cpu_timer</span><span style="background-color: #D7EEFF"> t;</span>
for (long i = 0; i &lt; 100000000; ++i)
std::sqrt(123.456L); // burn some time
return 0;
}</pre>
</blockquote>
<p>When the <code>auto_cpu_timer</code> 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, <code>std::cout</code>.</p>
<p>The output of this program, run with a debug build on a circa 2006 desktop processor:</p>
<p><code>&nbsp;&nbsp;&nbsp; 5.713010s wall, 5.709637s user + 0.000000s system =
5.709637s CPU (99.9%)</code></p>
<p>In other words, this program ran in <code>5.713010</code> seconds as would be measured by a
clock on the wall, the operating system charged it for <code>5.709637</code> seconds of user CPU
time and 0 seconds of system CPU time, the total of these two was <code>5.709637</code>, and that
represented <code>99.9</code> percent of the wall clock time.</p>
<p>The output stream, number of decimal places reported, and reporting format
can be controlled by <code>auto_cpu_timer</code> constructor arguments. Here is
what the output from the above program would look like for several different
sets of constructor arguments:</p>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
<tr>
<td><i><b>Constructor</b></i></td>
<td><i><b>Resulting Output</b></i></td>
</tr>
<tr>
<td><code><font size="1">t</font></code></td>
<td><code><font size="1">5.713010s wall, 5.709637s user + 0.000000s system = 5.709637s
CPU (99.9%)</font></code></td>
</tr>
<tr>
<td><code><font size="1">t(std::cerr</font><font size="1">, 2)</font></code></td>
<td><code><font size="1">5.71s wall, 5.70s user + 0.00s system = 5.70s CPU (99.9%)</font></code></td>
</tr>
<tr>
<td><code><font size="1">t(1)</font></code></td>
<td><code><font size="1">5.7s wall, 5.7s user + 0.0s system = 5.7s CPU (99.9%)</font></code></td>
</tr>
<tr>
<td><code><font size="1">t(3, &quot;%w seconds\n&quot;)</font></code></td>
<td><code><font size="1">5.713 seconds<br>
&nbsp;</font></code></td>
</tr>
<tr>
<td><code><font size="1">t(&quot;%t</font><font size="1"> sec CPU, %w sec real&quot;)
</font> </code></td>
<td><code><font size="1">5.709637 sec CPU, 5.713010 sec real</font></code></td>
</tr>
</table>
<p> The processing of the format string is described <a href="#format">here</a>.</p>
<h3> Using <code><a name="using-cpu_timer">cpu_timer</a></code></h3>
<p> The following code creates a checkpoint every 20 seconds of user CPU time:</p>
<blockquote>
<pre>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 &gt; 20*1000000000LL)
{
... create a checkpoint ...
last_checkpoint_time = checkpoint_timer.elapsed().user;
}
}</pre>
</blockquote>
<h2> <a name="Reference">Reference</a></h2>
<p> Specifications are given in the style of the C++ standard library (C++11,
17.5.1.4 [structure.specifications]). An additional <i>Overview</i> element may
be provided to aid understanding. <i>Overview</i> elements are only informative
- actual semantics are given by the other detailed specification elements.</p>
<p dir="ltr"> Functions not specified as <code>noexcept</code> will throw <code>
std::bad_alloc</code> exceptions if a memory allocation error occurs. Other
errors are reported by time values of -1. [<i>Note:</i> Modern hardware and
operating systems have robust clock subsystems, so such errors are unusual if
even possible at all. <i>-- end note</i>]</p>
<p dir="ltr"> 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], <i>Shared objects and the
library</i>. </p>
<h3>
<code>&lt;boost/timer/timer.hpp&gt;</code>
<a name="Synopsis">Synopsis</a></h3>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
<tr>
<td bgcolor="#D7EEFF">
<blockquote>
<pre>namespace boost
{
namespace timer
{
class <a href="#Class-cpu_timer">cpu_timer</a>; // wall-clock, user, and system timer
class <a href="#Class-auto_cpu_timer">auto_cpu_timer</a>; // 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 <a name="default_places">default_places</a> = 6;
const std::string&amp; <a href="#default_format">default_format</a>();
std::string format(const cpu_times&amp; times,
short places = default_places,
const std::string&amp; format = default_format());
} // namespace timer
} // namespace boost</pre>
</blockquote>
</td>
</tr>
</table>
<h3>Typedef <a name="nanosecond_type"><code>nanosecond_type</code></a></h3>
<p>The typedef <code>nanosecond_type</code> provides an implementation defined type capable
of representing nanoseconds. For POSIX and Windows systems, <code>
nanoseconds_type</code> is <code>boost::int_least64_</code>t.</p>
<p>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.</p>
<p>Although <code>nanosecond_type</code> is capable of representing one <b>
nanosecond</b>, 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 <b>microsecond</b>. For user and system time, typical
resolution is 15 <b>milliseconds</b> on Windows and 10 <b>milliseconds</b> on
POSIX.</p>
<h3><a name="cpu_times">Struct <code>cpu_times</code></a></h3>
<p>Struct <code>cpu_times</code> packages three elapsed times:</p>
<ul>
<li>Wall clock elapsed time, equivalent to the time that would be recorded by
a stopwatch.</li>
<li>User central processing unit (CPU) time used by the process, as charged by
the operating system.</li>
<li>System central processing unit (CPU) time used by the process, as charged
by the operating system.</li>
</ul>
<h3><a name="Non-member-functions">Non-member functions</a></h3>
<pre><span style="background-color: #D7EEFF">const std::string&amp; </span><span style="background-color: #D7EEFF"><a name="default_format">default_format</a>();</span></pre>
<blockquote>
<p><i>Returns:</i> <code>std::string(&quot; %ws wall, %us user + %ss system = %ts
CPU (%p%)\n&quot;)</code>.</p>
</blockquote>
<pre><span style="background-color: #D7EEFF">std::string </span><a name="format"><span style="background-color: #D7EEFF">format</span></a><span style="background-color: #D7EEFF">(const</span><span style="background-color: #D7EEFF"> </span><a href="#cpu_times"><span style="background-color: #D7EEFF">cpu_times</span></a><span style="background-color: #D7EEFF">&amp; times,
short places = </span><span style="background-color: #D7EEFF"><a href="#default_places">default_places</a>,
const std::string&amp; format = <a href="#default_format">default_format</a>()); </span></pre>
<blockquote>
<p><i>Overview: </i>Converts the <code>times</code> argument's values to strings
representing seconds to a given number of decimal <code>places</code>, and
inserts them into a return string under control of the <code>format</code>
string.</p>
<p><i>Effects:</i> If <code>places</code> is less than 0,&nbsp; it is set to <code>default_places</code>. If <code>places</code> is
more than 9, it is set to 9. if the <code>format</code>
argument is <code>empty()</code>, it is set to <code>
default_format</code>.</p>
<p><i>Returns:</i> A string that is a copy of <code>format</code>, except that any
instances of the sequences shown below are replaced by the indicated value.
Times are reported in seconds,
shown to <code>places</code> decimal places. Percentage is reported to one
decimal place. [<i>Note:</i> percentage may exceed 100% due to differences in
how operating systems measure various times. <i>--end note</i>]</p>
<p><i><b><a name="Format-replacement-sequences">Format replacement sequences</a></b></i></p>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="39%">
<tr>
<td width="25%"><b><i>Sequence</i></b></td>
<td width="75%"><b><i>Replacement value</i></b></td>
</tr>
<tr>
<td width="25%" align="center"><code>%w</code></td>
<td width="75%"><code>times.wall</code></td>
</tr>
<tr>
<td width="25%" align="center"><code>%u</code></td>
<td width="75%"><code>times.user</code></td>
</tr>
<tr>
<td width="25%" align="center"><code>%s</code></td>
<td width="75%"><code>times.system</code></td>
</tr>
<tr>
<td width="25%" align="center"><code>%t</code></td>
<td width="75%"><code>times.user + times.system</code></td>
</tr>
<tr>
<td width="25%" align="center"><code>%p</code></td>
<td width="75%">The percentage of <code>times.wall</code> represented by <code>
times.user + times.system</code></td>
</tr>
</table>
</blockquote>
<h3><a name="Class-cpu_timer">Class <code>cpu_timer</code></a></h3>
<p> <code>cpu_timer</code> objects measure wall-clock elapsed time, process elapsed
time charged to the user, and process elapsed time charged to the system.</p>
<p><i><b><a name="Current-time-values">Current time values</a></b></i> are
obtained as follows: Current wall-clock time is obtained from the Boost.Chrono <code>
high_resolution_clock</code>. Current user and system time values are obtained
from the appropriate operating system API functions such as <code>times()</code>
on POSIX or <code>
GetProcessTimes()</code> on Windows.</p>
<h3> <a name="cpu_timer-synopsis"> <code>cpu_timer</code> synopsis</a></h3>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
<tr>
<td bgcolor="#D7EEFF">
<pre>
class <a name="cpu_timer">cpu_timer</a>
{
public:
// constructor, destructor
<a href="#cpu_timer-ctor">cpu_timer</a>() noexcept;
<a href="#cpu_timer-dtor">~cpu_timer</a>() noexcept {}
// compiler generated
cpu_timer(const cpu_timer&amp;) = default;
cpu_timer&amp; operator=(const cpu_timer&amp;) = default;
// observers
bool <a href="#is_stopped">is_stopped</a>() const noexcept;
cpu_times <a href="#elapsed">elapsed</a>() const noexcept;
std::string <a href="#cpu_timer-format">format</a>(int places = default_places,
const std::string&amp; format = default_format()) const;
// actions
void <a href="#start">start</a>() noexcept;
const cpu_times&amp; <a href="#stop">stop</a>() noexcept;
void <a href="#resume">resume</a>() noexcept;
};</pre>
</td>
</tr>
</table>
<h3><a name="cpu_timer-constructors"><code>cpu_timer</code> constructor</a>, destructor</h3>
<pre><span style="background-color: #D7EEFF"><a name="cpu_timer-ctor">cpu_timer</a>() noexcept;</span></pre>
<blockquote>
<p><i>Effects:</i> Constructs an object of type <code>
cpu_timer</code>. Calls<code> start()</code>.</p>
</blockquote>
<pre><span style="background-color: #D7EEFF">~<a name="cpu_timer-dtor">cpu_timer</a>() noexcept {}</span></pre>
<blockquote>
<p><i>Effects:</i> None</p>
</blockquote>
<h3><a name="cpu_timer-observers"><code>cpu_timer</code>
observers</a></h3>
<pre><span style="background-color: #D7EEFF">bool</span><span style="background-color: #D7EEFF"> <a name="is_stopped">is_stopped</a>() const noexcept;</span></pre>
<blockquote>
<p><i>Returns:</i> <code>true</code> if the most recent call to an
<a href="#cpu_timer-actions">action</a> function was to <a href="#stop">stop()</a>,
otherwise <code>false</code>.</p>
</blockquote>
<pre><span style="background-color: #D7EEFF">cpu_times</span><span style="background-color: #D7EEFF"> <a name="elapsed">elapsed</a>() const noexcept;</span></pre>
<blockquote>
<p><i>Overview:</i> If the timer is running, returns the cumulative elapsed
time. If the timer is stopped, returns the cumulative elapsed time previously
stored by <a href="#stop">stop()</a>.</p>
<p><i>Returns:</i> If <code>is_stopped()</code>, the stored time values.
Otherwise, the difference between the
<a href="#Current-time-values">current time values</a> and the stored time
values.</p>
</blockquote>
<pre><span style="background-color: #D7EEFF">std::string <a name="cpu_timer-format">format</a>(int</span><span style="background-color: #D7EEFF"> places = </span><span style="background-color: #D7EEFF"><a href="#default_places">default_places</a>,
const std::string&amp; format = <a href="#default_format">default_format</a>()) const;</span></pre>
<blockquote>
<p><i>Overview:</i> Returns a string for the current elapsed time as formatted
by the <a href="#format">format function</a>.</p>
<p><i>Returns:</i> <code><a href="#format">timer::format</a>(<a href="#elapsed">elapsed</a>(), places, format)</code>.</p>
</blockquote>
<h3><a name="cpu_timer-actions"><code>cpu_timer</code>
actions</a></h3>
<pre><span style="background-color: #D7EEFF">void <a name="start">start</a>() noexcept;</span></pre>
<blockquote>
<p dir="ltr"><i>Effects:</i> Stores the <a href="#Current-time-values">current time values</a>.</p>
<p><i>Postconditions:</i> <code>!is_stopped()</code>.</p>
</blockquote>
<pre><span style="background-color: #D7EEFF">cpu_times</span><span style="background-color: #D7EEFF"> <a name="stop">stop</a>() noexcept;</span></pre>
<blockquote>
<p><i>Effects:</i> If <code>!is_stopped()</code>, stores the difference between
the <a href="#Current-time-values">current time values</a> and the time values
stored by the most recent call to <a href="#start">start()</a> or
<a href="#resume">resume()</a>.</p>
<p><i>Postconditions:</i> <code>is_stopped()</code>.</p>
<p><i>Returns:</i> The stored times.</p>
</blockquote>
<pre><span style="background-color: #D7EEFF">void <a name="resume">resume</a>() noexcept;</span></pre>
<blockquote>
<p><i>Overview:</i> Restarts the timer, accumulating additional elapsed time.</p>
<p><i>Effects:</i> If is_stopped(), store the
<a href="#Current-time-values">current time values</a> less the previously
stored cumulative elapsed times.&nbsp; Otherwise, no effect. [<i>Note</i>:
Subtracting the previous elapsed times has the effect of accumulating
additional elapsed time. <i>--end note</i>]</p>
</blockquote>
<h3><a name="Class-auto_cpu_timer">Class <code>auto_cpu_timer</code></a></h3>
<p>Class <code>auto_cpu_timer</code> adds a <code>report()</code>
function to <code>class cpu_timer</code>, and automatically calls <code>report()</code>
on destruction.</p>
<h3> <a name="auto_cpu_timer-synopsis"> <code>auto_cpu_timer</code> synopsis</a></h3>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%">
<tr>
<td bgcolor="#D7EEFF">
<pre>
class <a name="auto_cpu_timer">auto_cpu_timer</a> : public <a href="#cpu_timer">cpu_timer</a>
{
public:
explicit <a href="#auto_cpu_timer-1">auto_cpu_timer</a>(short places = <a href="#default_places">default_places</a>,
const std::string&amp; format = <a href="#default_format">default_format</a>());
explicit <a href="#auto_cpu_timer-2">auto_cpu_timer</a>(const std::string&amp; format);
explicit <a href="#auto_cpu_timer-3">auto_cpu_timer</a>(std::ostream&amp; os,
short places = <a href="#default_places">default_places</a>,
const std::string&amp; format = <a href="#default_format">default_format</a>());
<a href="#auto_cpu_timer-4">auto_cpu_timer</a>(std::ostream&amp; os, const std::string&amp; format);
<a href="#auto_cpu_timer-destructor">~auto_cpu_timer</a>() noexcept;
cpu_timer(const cpu_timer&amp;) = default;
cpu_timer&amp; operator=(const cpu_timer&amp;) = default;
void <a href="#report">report</a>();
private:
std::ostream& m_os; // <b><i>exposition only</i></b>
short m_places; // <b><i>exposition only</i></b>
std::string m_format; // <b><i>exposition only</i></b>
};</pre>
</td>
</tr>
</table>
<p dir="ltr">[<i>Note:</i> Constructors without a <code>std::ostream&amp;</code>
argument argument imply <code>
std::cout</code>. An argument default is avoided as it would require including <code>&lt;iostream&gt;</code>,
with its high costs, even when the standard streams are not used. <i>--end note</i>]</p>
<h3><a name="auto_cpu_timer-constructors"><code>auto_cpu_timer</code> constructors</a></h3>
<pre><span style="background-color: #D7EEFF">explicit <a name="auto_cpu_timer-1">auto_cpu_timer</a>(short places = </span><a href="#default_places"><span style="background-color: #D7EEFF">default_places</span></a><span style="background-color: #D7EEFF">,
const std::string&amp; format = default_format());</span></pre>
<blockquote>
<p><i>Effects:</i> Constructs an object of type <code>
auto_cpu_timer</code>.</p>
<p><i>Postconditions:
</i>As if<i><br>
</i><code>&nbsp; m_os == std::cout</code>,<code><br>
&nbsp; m_places == places</code>,<code><br>
&nbsp; m_format == format</code></p>
</blockquote>
<pre><span style="background-color: #D7EEFF">explicit <a name="auto_cpu_timer-2">auto_cpu_timer</a>(const</span><span style="background-color: #D7EEFF"> std::string&amp; format);</span></pre>
<blockquote>
<p><i>Effects:</i> Constructs an object of type <code>
auto_cpu_timer</code>.</p>
<p><i>Postconditions:
</i>As if<i><br>
</i><code>&nbsp; m_os == std::cout</code>,<code><br>
&nbsp; m_places == default_places</code>,<code><br>
&nbsp; m_format == format</code></p>
</blockquote>
<pre><span style="background-color: #D7EEFF">explicit <a name="auto_cpu_timer-3">auto_cpu_timer</a>(std::ostream</span><span style="background-color: #D7EEFF">&amp; </span><span style="background-color: #D7EEFF">os</span><span style="background-color: #D7EEFF">,
short places = </span><a href="#default_places">default_places</a><span style="background-color: #D7EEFF">,
const std::string&amp; format = </span><span style="background-color: #D7EEFF">default_format());</span></pre>
<blockquote>
<p><i>Effects:</i> Constructs an object of type <code>
auto_cpu_timer</code>.</p>
<p><i>Postconditions:
</i>As if<i><br>
</i><code>&nbsp; m_os == os</code>,<code><br>
&nbsp; m_places == places</code>,<code><br>
&nbsp; m_format == format</code></p>
</blockquote>
<pre><span style="background-color: #D7EEFF"><a name="auto_cpu_timer-4">auto_cpu_timer</a>(std::ostream</span><span style="background-color: #D7EEFF">&amp; </span><span style="background-color: #D7EEFF">os</span><span style="background-color: #D7EEFF">, const std::string&amp; format);</span></pre>
<blockquote>
<p><i>Effects:</i> Constructs an object of type <code>
auto_cpu_timer</code>.</p>
<p><i>Postconditions:
</i>As if<i><br>
</i><code>&nbsp; m_os == os</code>,<code><br>
&nbsp; m_places == </code><a href="#default_places">default_places</a>,<code><br>
&nbsp; m_format == format</code></p>
</blockquote>
<h3><a name="auto_cpu_timer-destructor"><code>auto_cpu_timer</code> destructor</a></h3>
<pre><span style="background-color: #D7EEFF">~</span><span style="background-color: #D7EEFF">auto_cpu_timer</span><span style="background-color: #D7EEFF">() noexcept;</span></pre>
<blockquote>
<p dir="ltr"><i>Effects: </i>If <code>!is_stopped()</code>, <a href="#report">
report()</a>. Otherwise, no effects.</p>
<p dir="ltr">[<i>Note:</i> Because the function is <code>noexcept</code>,
implementation requires a try/catch or equivalent to ensure no exception
escapes. <i>--end note</i>]</p>
</blockquote>
<h3><a name="auto_cpu_timer-actions"><code>auto_cpu_timer</code> actions</a></h3>
<pre><span style="background-color: #D7EEFF">void <a name="report">report</a>();</span></pre>
<blockquote>
<p><i>Effects: </i>As if:</p>
<blockquote>
<pre>m_os &lt;&lt; timer::format(stop(), m_places, m_format);
resume();</pre>
</blockquote>
<p>[<i>Note:</i> <code>stop()</code> is called because doing I/O while the
timer is running might produce misleading results. <i>--end note</i>]</p>
</blockquote>
<h2><a name="Timer-accuracy">Timer accuracy</a></h2>
<p>How accurate are these timers? </p>
<h3><a name="Resolution">Resolution</a></h3>
<p dir="ltr">The resolution of a clock, and thus timers built on that clock,
is the minimum period time that can be measured. The program <code>
<a href="../test/cpu_timer_info.cpp">cpu_timer_info.cpp</a></code> measures
the resolution of <code>cpu_timer</code>.</p>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
<tr>
<td rowspan="2">O/S</td>
<td rowspan="2">Processor</td>
<td colspan="2" align="center">Wall-clock</td>
<td colspan="2" align="center">CPU</td>
</tr>
<tr>
<td>Resolution</td>
<td>Comments</td>
<td align="center">User<br>
Resolution</td>
<td align="center">System<br>
Resolution</td>
</tr>
<tr>
<td>Windows 7</td>
<td>Intel Core i7 860 @ 2.9 GHz</td>
<td align="right">366ns</td>
<td>Some variation, usually in multiples of 366ns</td>
<td>15600100ns</td>
<td>15600100ns</td>
</tr>
<tr>
<td>Windows 7</td>
<td>Intel Mobile T7200 @ 2.0 GHz</td>
<td align="right">2050ns</td>
<td>Much variation. Resolution degrades when processor slows, probably due
to known chipset errata. </td>
<td>15600100ns</td>
<td>15600100ns</td>
</tr>
<tr>
<td>Windows XP</td>
<td>Intel Atom N2800 @ 1.0 GHz</td>
<td align="right">1437ns</td>
<td>Some variation.</td>
<td>15625000ns</td>
<td>15625000ns</td>
</tr>
<tr>
<td>Mac OS X Lion</td>
<td>Intel circa 2007</td>
<td align="right">2100ns<br>
2200ns</td>
<td>Some variation within a range.</td>
<td>10000000ns</td>
<td>10000000ns</td>
</tr>
<tr>
<td>Ubuntu Linux 11.4</td>
<td>Intel circa 2005</td>
<td align="right">516ns</td>
<td>Very little variation, typically less than 5ns </td>
<td>10000000ns</td>
<td>10000000ns</td>
</tr>
</table>
<h3><a name="Other-concerns">Other concerns</a></h3>
<p>Wall-clock timings are subject to many outside influences, such as the impact
of other processes.</p>
<blockquote>
<p><code>cpu_timer</code> and <code>auto_cpu_timer</code> obtain Wall-clock
timings from Boost.Chrono's <code>high_resolution_clock</code>. On Intel
compatible CPU's running Windows, Linux, and Mac OS X, this is a &quot;steady
clock&quot;, but may not be steady on other platforms. <code>
<a href="../test/cpu_timer_info.cpp">cpu_timer_info.cpp</a></code> reports
whether or not the <code>high_resolution_clock</code> is steady on a
particular platform.</p>
<p><i><b><a name="Steady-clocks">Steady clocks</a></b></i> are defined by the
C++11 standard as clocks for which values never decrease as physical time
advances and for which values advance at a steady rate relative to real time.
That is, the clock may not be adjusted. Clocks that are steady never run
backwards, even when the operating system's clock is reset backwards such as
during a daylight saving time transition.</p>
</blockquote>
<p>Timings of debug builds are often several times slower
than release builds, because compiler optimization is turned off and
because libraries often supply very expensive error checks on debug builds.</p>
<p>Synthetic benchmark code may be optimized way by release builds. It may be
necessary to inspect generated code to verify this isn't happening.</p>
<h3 dir="ltr"><a name="Recommendations">Recommendations</a></h3>
<p dir="ltr">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, total CPU time (user + system) is often a much better measure.</p>
<p dir="ltr">A useful recommendation 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.</p>
<p>Shared libraries (DLL's) may incur extra time delays, including expensive
disk accesses, the first time a timer or other function is called. If that
would be misleading, static linking should be considered.</p>
<h2><a name="History">History</a></h2>
<p>Beman Dawes and Rob Stewart developed version 2 of the library.</p>
<p>Beman did the initial development. Rob contributed many corrections, comments, and suggestions. In
particular, he suggested the <code>resume()</code> and <code>format()</code>
functions, resulting in improved ease-of-use for several use cases.</p>
<h2><a name="Acknowledgements">Acknowledgements</a></h2>
<p>Comments and suggestions came from Greg Rubino, Dave Abrahams, Vicente
Botet, and John Maddock.</p>
<hr>
<p><font size="2">Revised:
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->04 October 2011<!--webbot bot="Timestamp" endspan i-checksum="32185" --></font></p>
<p><font size="2">© Copyright Beman Dawes, 2006<br>
© Copyright Beman Dawes and Robert Stewart, 2011</font></p>
<p><font size="2">Distributed under the Boost Software License, Version 1.0. See <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/ LICENSE_1_0.txt</a></font></p>
</body>
</html>

87
doc/index.html Normal file
View File

@@ -0,0 +1,87 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Boost Timer Library</title>
<style type="text/css">
ins {background-color:#A0FFA0}
del {background-color:#FFA0A0}
body
{
font-family: sans-serif;
max-width : 8.5in;
margin: 1em;
}
</style>
</head>
<body>
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="750">
<tr>
<td width="300">
<a href="../../../index.htm">
<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="300" height="86" border="0"></a></td>
<td align="middle" width="430">
<font size="7">Timer Library<br>
Version 2</font>
</td>
</tr>
</table>
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%">
<tr>
<td><a href="index.html">Timer Home</a> &nbsp;&nbsp;
<a href="cpu_timers.html">CPU timers</a> &nbsp;&nbsp;
<a href="original_timer.html">Original timers</a> &nbsp;&nbsp;
</td>
</tr>
</table>
<p>&quot;How long does my C++ code take to run?&quot;<p>The Boost Timer library
answers that question - portably, and with as little as one #include and one
additional line of code.<p>The Boost Timer library has two distinct sets of
components.<ul>
<li>If you are new to the library, please go directly to the version 2
<a href="cpu_timers.html">CPU timers</a> page.<br>
&nbsp;</li>
<li>If you are interested in
the original library, now deprecated, read on below.</li>
</ul>
<h2>
<a href="cpu_timers.html">CPU timers</a></h2>
<p>These version 2 components conform to current Boost practice:</p>
<ul>
<li>The interfaces and their semantics are the same across all platforms.</li>
<li>The internal implementation uses operating system specific APIs to achieve
higher precision and supply functionality not otherwise available.&nbsp; </li>
<li>The headers live in a sub-directory, <code>&lt;boost/timer/...&gt;</code>.</li>
<li>The content is in a sub-namespace, <code>boost::timer</code>.</li>
</ul>
<h2 dir="ltr">
<a href="original_timer.html">Original timers</a></h2>
<p>These version 1 components are deprecated. They date from the earliest days
of Boost and do not conform to current Boost practice:</p>
<ul>
<li>The interfaces are the same across all platforms, but the semantics differ
according to platform. Wall-clock time is measured on Windows, while CPU time
is measured on POSIX-like systems.</li>
<li>The internal implementation uses only C/C++ standard library functions, so
cannot supply desirable precision and functionality.</li>
<li>The headers live in the main Boost header directory.</li>
<li>The content are in namespace <code>boost</code>.</li>
</ul>
<hr>
<p><font size="2">Revised:
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->04 October 2011<!--webbot bot="Timestamp" endspan i-checksum="32185" --></font></p>
<p><font size="2">© Copyright Beman Dawes&nbsp; 2001, 2011</font></p>
<p><font size="2">Distributed under the Boost Software License, Version 1.0. See
</font>
<a href="http://www.boost.org/LICENSE_1_0.txt"><font size="2">www.boost.org/LICENSE_1_0.txt</font></a></p>
</body>
</html>

View File

@@ -5,14 +5,66 @@
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Boost Timer Documentation</title>
<title>Original Timers</title>
<style type="text/css">
ins {background-color:#A0FFA0}
del {background-color:#FFA0A0}
body
{
font-family: sans-serif;
max-width : 8.5in;
margin: 1em;
}
</style>
</head>
<body bgcolor="#FFFFFF" text="#000000">
<h1>
<img src="../../boost.png" alt="boost.png (6897 bytes)" align="center" width="277" height="86">
Timer Library</h1>
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="750">
<tr>
<td width="300">
<a href="../../../index.htm">
<img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="300" height="86" border="0"></a></td>
<td align="middle" width="430">
<font size="7">Timer Library<br>
Original Timers and Progress Display</font></td>
</tr>
</table>
<table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%">
<tr>
<td><a href="index.html">Timer Home</a> &nbsp;&nbsp;
<a href="cpu_timers.html">CPU timers</a> &nbsp;&nbsp;
<a href="original_timer.html">Original timers</a> &nbsp;&nbsp;
</td>
</tr>
</table>
<p></p>
<center>
<table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="80%">
<tr>
<td width="100%" bgcolor="#FFFF66">
<p><i><b>These timers are deprecated.</b></i> They date from the earliest days
of Boost and do not conform
to current Boost practice.</p>
<ul>
<li>The interfaces are the same across all platforms, but the semantics differ
according to platform. Wall-clock time is measured on Windows, while CPU time
is measured on POSIX-like systems.</li>
<li>The internal implementation uses only C/C++ standard library functions, so
cannot supply desirable precision and functionality.</li>
<li>The headers live in the main Boost header directory.</li>
<li>The content are in namespace <code>boost</code>.</li>
</ul>
Please see the Version 2
<a href="cpu_timers.html">CPU timers</a> for replacements that conform to
current Boost practice.</td>
</tr>
</table>
</center>
<p>The timer library provides two headers and three classes: </p>
<blockquote>
@@ -201,12 +253,14 @@ compiler (Microsoft and Borland were tested) and the operating system version
(Windows NT, Windows 95, etc.)&nbsp; Thus the std::clock() function was much
more reliable, and so was retained even on this platform with its own timer API.</p>
<hr>
<p>© Copyright Beman Dawes 1999.<br>
Distributed under the Boost Software License, Version 1.0. See
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
<p><font size="2">Revised:
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->04 October 2011<!--webbot bot="Timestamp" endspan i-checksum="32185" --></font></p>
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%B %d, %Y" startspan -->November 07, 2007<!--webbot bot="Timestamp" i-checksum="39599" endspan -->
</p>
<p><font size="2">© Copyright Beman Dawes 1999.</font></p>
<p><font size="2">Distributed under the Boost Software License, Version 1.0. See
</font>
<a href="http://www.boost.org/LICENSE_1_0.txt"><font size="2">www.boost.org/LICENSE_1_0.txt</font></a></p>
</body>

View File

@@ -0,0 +1,19 @@
// auto_cpu_timer_example.cpp ------------------------------------------------------//
// Copyright Beman Dawes 2006
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
#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;
}

47
example/timex.cpp Normal file
View File

@@ -0,0 +1,47 @@
// timex: timed execution program ------------------------------------------//
// Copyright Beman Dawes 2007
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
// See http://www.boost.org/libs/timer for documentation.
#include <boost/timer/timer.hpp>
#include <cstdlib>
#include <string>
#include <iostream>
int main( int argc, char * argv[] )
{
if ( argc == 1 )
{
std::cout << "invoke: timex [-v] command [args...]\n"
" command will be executed and timings displayed\n"
" -v option causes command and args to be displayed\n";
return 1;
}
std::string s;
bool verbose = false;
if ( argc > 1 && *argv[1] == '-' && *(argv[1]+1) == 'v' )
{
verbose = true;
++argv;
--argc;
}
for ( int i = 1; i < argc; ++i )
{
if ( i > 1 ) s += ' ';
s += argv[i];
}
if ( verbose )
{ std::cout << "command: \"" << s.c_str() << "\"\n"; }
boost::timer::auto_cpu_timer t(" %ws elapsed wall-clock time\n");
return std::system( s.c_str() );
}

View File

@@ -0,0 +1,53 @@
// boost/timer/config.hpp -----------------------------------------------------------//
// Copyright Beman Dawes 2003, 2006, 2011
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
// See http://www.boost.org/libs/timer for documentation.
#ifndef BOOST_TIMER_CONFIG_HPP
#define BOOST_TIMER_CONFIG_HPP
#include <boost/config.hpp>
#include <boost/system/api_config.hpp>
// This header implements separate compilation features as described in
// http://www.boost.org/more/separate_compilation.html
// enable dynamic or static linking as requested --------------------------------------//
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_TIMER_DYN_LINK)
# if defined(BOOST_TIMER_SOURCE)
# define BOOST_TIMER_DECL BOOST_SYMBOL_EXPORT
# else
# define BOOST_TIMER_DECL BOOST_SYMBOL_IMPORT
# endif
#else
# define BOOST_TIMER_DECL
#endif
// enable automatic library variant selection ----------------------------------------//
#if !defined(BOOST_TIMER_SOURCE) && !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_TIMER_NO_LIB)
//
// Set the name of our library, this will get undef'ed by auto_link.hpp
// once it's done with it:
//
#define BOOST_LIB_NAME boost_timer
//
// If we're importing code from a dll, then tell auto_link.hpp about it:
//
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_TIMER_DYN_LINK)
# define BOOST_DYN_LINK
#endif
//
// And include the header that does the work:
//
#include <boost/config/auto_link.hpp>
#endif // auto-linking disabled
#endif // BOOST_TIMER_CONFIG_HPP

View File

@@ -0,0 +1,130 @@
// boost/timer/timer.hpp -------------------------------------------------------------//
// Copyright Beman Dawes 1994-2007, 2011
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
#ifndef BOOST_TIMER_TIMER_HPP
#define BOOST_TIMER_TIMER_HPP
#include <boost/config/warning_disable.hpp>
#include <boost/timer/config.hpp>
#include <boost/chrono/chrono.hpp>
#include <boost/cstdint.hpp>
#include <string>
#include <cstring>
#include <ostream>
#include <boost/config/abi_prefix.hpp> // must be the last #include
# if defined(_MSC_VER)
# pragma warning(push) // Save warning settings
# pragma warning(disable : 4251) // disable warning: class 'std::basic_string<_Elem,_Traits,_Ax>'
# endif // needs to have dll-interface...
//--------------------------------------------------------------------------------------//
// TODO:
//
// * Add BOOST_NOEXCEPT where applicable
//--------------------------------------------------------------------------------------//
namespace boost
{
namespace timer
{
class cpu_timer;
class auto_cpu_timer;
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 short default_places = 6;
BOOST_TIMER_DECL
const std::string& default_format();
BOOST_TIMER_DECL
std::string format(const cpu_times& times,
short places = default_places,
const std::string& fmt = default_format());
// cpu_timer ---------------------------------------------------------------------//
class BOOST_TIMER_DECL cpu_timer
{
public:
// constructors, destructor
cpu_timer() { start(); }
~cpu_timer() {}
// observers
bool is_stopped() const { return m_is_stopped; }
cpu_times elapsed() const; // does not stop()
std::string format(int places = default_places,
const std::string& format = default_format()) const
{ return timer::format(elapsed(), places, format); }
// actions
void start();
const cpu_times& stop();
void resume();
private:
cpu_times m_times;
bool m_is_stopped;
};
// auto_cpu_timer --------------------------------------------------------------------//
class BOOST_TIMER_DECL auto_cpu_timer : public cpu_timer
{
public:
// Explicit defaults to std::cout are not supplied since such defaults would
// require including <iostream>, with its high costs, even when the standard
// streams are not actually used.
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())
: m_places(places), m_os(os), m_format(format)
{ start(); }
auto_cpu_timer(std::ostream& os, const std::string& format)
: m_places(default_places), m_os(os), m_format(format)
{ start(); }
~auto_cpu_timer();
void report();
private:
int m_places;
std::ostream& m_os;
std::string m_format;
};
} // namespace timer
} // namespace boost
# if defined(_MSC_VER)
# pragma warning(pop) // restore warning settings.
# endif
#include <boost/config/abi_suffix.hpp> // pops abi_prefix.hpp pragmas
#endif // BOOST_TIMER_TIMER_HPP

View File

@@ -1,47 +1,14 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Boost Timer Library</title>
<meta http-equiv="refresh" content="0; URL=v3/doc/index.htm">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<table border="1" bgcolor="#007F7F" cellpadding="2">
<tr>
<td bgcolor="#FFFFFF"><img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86"></td>
<td><a href="../../index.htm"><font face="Arial" color="#FFFFFF"><big>Home </big></font></a></td>
<td><a href="../libraries.htm"><font face="Arial" color="#FFFFFF"><big>Libraries </big></font></a></td>
<td><a href="http://www.boost.org/people/people.htm"><font face="Arial" color="#FFFFFF"><big>People </big></font></a></td>
<td><a href="http://www.boost.org/more/faq.htm"><font face="Arial" color="#FFFFFF"><big>FAQ </big></font></a></td>
<td><a href="../../more/index.htm"><font face="Arial" color="#FFFFFF"><big>More </big></font></a></td>
</tr>
</table>
<h1>Timer library</h1>
<p>The timer library supplies a timer class for measuring elapsed time, a
progress_timer class for reporting elapsed time, and a progress_display class
for displaying an indication of progress toward a goal.
<ul>
<li><a href="timer.htm">Documentation</a> (HTML).</li>
<li>Headers <a href="../../boost/timer.hpp">timer.hpp</a> and <a href="../../boost/progress.hpp">progress.hpp</a></li>
<li>Test program <a href="test/timer_test.cpp">timer_test.cpp</a></li>
<li>Submitted by <a href="http://www.boost.org/people/beman_dawes.html">Beman Dawes</a>.</li>
</ul>
<p>&nbsp;</p>
<body>
Automatic redirection failed, please go to <a href="doc/index.html">doc/index.html</a>.
<hr>
<p>© Copyright Beman Dawes, 2001<br>
Distributed under the Boost Software License, Version 1.0. See
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
<p><!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->07 November, 2007<!--webbot bot="Timestamp" endspan i-checksum="39369" -->
</p>
<p>&copy; Copyright Beman Dawes, 2003, 2011</p>
<p> Distributed under the Boost Software
License, Version 1.0.</p>
<p> See <a href="http://www.boost.org/LICENSE_1_0.txt">
www.boost.org/LICENSE_1_0.txt</a></p>
</body>
</html>

130
src/auto_timers.cpp Normal file
View File

@@ -0,0 +1,130 @@
// boost auto_cpu_timer.cpp -----------------------------------------------------//
// Copyright Beman Dawes 1994-2006, 2011
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt)
//----------------------------------------------------------------------------//
// define BOOST_TIMER_SOURCE so that <boost/timer/config.hpp> knows
// the library is being built (possibly exporting rather than importing code)
#define BOOST_TIMER_SOURCE
#include <boost/timer/timer.hpp>
#include <boost/io/ios_state.hpp>
#include <string>
#include <sstream>
#include <cstring>
using boost::timer::nanosecond_type;
using boost::timer::cpu_times;
using boost::system::error_code;
# if defined(BOOST_WINDOWS_API)
# include <windows.h>
# elif defined(BOOST_POSIX_API)
# include <sys/times.h>
# else
# error unknown API
# endif
namespace
{
// cpu_timer helpers ---------------------------------------------------------------//
void show_time(const cpu_times& times,
std::ostream& os, const std::string& fmt, short places)
// NOTE WELL: Will truncate least-significant digits to LDBL_DIG, which may
// be as low as 10, although will be 15 for many common platforms.
{
if (places > 9)
places = 9;
else if (places < 0)
places = boost::timer::default_places;
boost::io::ios_flags_saver ifs(os);
boost::io::ios_precision_saver ips(os);
os.setf(std::ios_base::fixed, std::ios_base::floatfield);
os.precision(places);
const long double sec = 1000000000.0L;
nanosecond_type total = times.system + times.user;
long double wall_sec = times.wall / sec;
long double total_sec = total / sec;
for (const char* format = fmt.c_str(); *format; ++format)
{
if (*format != '%' || !*(format+1) || !std::strchr("wustp", *(format+1)))
os << *format; // anything except % followed by a valid format character
// gets sent to the output stream
else
{
++format;
switch (*format)
{
case 'w':
os << times.wall / sec;
break;
case 'u':
os << times.user / sec;
break;
case 's':
os << times.system / sec;
break;
case 't':
os << total / sec;
break;
case 'p':
os.precision(1);
if (wall_sec > 0.001L && total_sec > 0.001L)
os << (total_sec/wall_sec) * 100.0;
else
os << "n/a";
os.precision(places);
break;
}
}
}
}
} // unnamed namespace
namespace boost
{
namespace timer
{
// format ------------------------------------------------------------------------//
BOOST_TIMER_DECL
std::string format(const cpu_times& times, short places, const std::string& fmt)
{
std::stringstream ss;
show_time(times, ss, fmt, places);
return ss.str();
}
// auto_cpu_timer ----------------------------------------------------------------//
void auto_cpu_timer::report()
{
show_time(stop(), m_os, m_format, m_places);
resume();
}
auto_cpu_timer::~auto_cpu_timer()
{
if (!is_stopped())
{
try
{
report();
}
catch (...) // eat any exceptions
{
}
}
}
} // namespace timer
} // namespace boost

View File

@@ -0,0 +1,37 @@
// boost auto_timers_construction.cpp ------------------------------------------------//
// Copyright Beman Dawes 2007, 2011
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/timer for documentation.
//--------------------------------------------------------------------------------------//
// These constructors are in a separate file so that this translation unit will
// not be linked in except when one of the constructors is actually used. This
// is important since header <iostream> is required, and it incurs the cost of
// the standard stream objects even if they are not used.
//--------------------------------------------------------------------------------------//
// define BOOST_TIMER_SOURCE so that <boost/timer/config.hpp> knows
// the library is being built (possibly exporting rather than importing code)
#define BOOST_TIMER_SOURCE
#include <boost/timer/timer.hpp>
#include <iostream>
namespace boost
{
namespace timer
{
auto_cpu_timer::auto_cpu_timer(short places, const std::string& format)
: m_places(places), m_os(std::cout), m_format(format) { start(); }
auto_cpu_timer::auto_cpu_timer(const std::string& format)
: m_places(default_places), m_os(std::cout), m_format(format) { start(); }
} // namespace timer
} // namespace boost

163
src/cpu_timer.cpp Normal file
View File

@@ -0,0 +1,163 @@
// boost cpu_timer.cpp ---------------------------------------------------------------//
// Copyright Beman Dawes 1994-2006, 2011
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/timer for documentation.
//--------------------------------------------------------------------------------------//
// define BOOST_TIMER_SOURCE so that <boost/timer/config.hpp> knows
// the library is being built (possibly exporting rather than importing code)
#define BOOST_TIMER_SOURCE
#include <boost/timer/timer.hpp>
#include <boost/chrono/chrono.hpp>
#include <boost/io/ios_state.hpp>
#include <boost/throw_exception.hpp>
#include <boost/cerrno.hpp>
#include <cstring>
#include <cassert>
# if defined(BOOST_WINDOWS_API)
# include <windows.h>
# elif defined(BOOST_POSIX_API)
# include <unistd.h>
# include <sys/times.h>
# else
# error unknown API
# endif
using boost::system::error_code;
namespace
{
# if defined(BOOST_POSIX_API)
boost::int_least64_t tick_factor() // multiplier to convert ticks
// to nanoseconds; -1 if unknown
{
static boost::int_least64_t tick_factor = 0;
if (!tick_factor)
{
if ((tick_factor = ::sysconf(_SC_CLK_TCK)) <= 0)
tick_factor = -1;
else
{
assert(tick_factor <= 1000000000LL); // logic doesn't handle large ticks
tick_factor = 1000000000LL / tick_factor; // compute factor
if (!tick_factor)
tick_factor = -1;
}
}
return tick_factor;
}
# endif
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)&current.system, (LPFILETIME)&current.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 == -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
}
} // unnamed namespace
namespace boost
{
namespace timer
{
BOOST_TIMER_DECL
const std::string& default_format()
{
static std::string fmt(" %ws wall, %us user + %ss system = %ts CPU (%p%)\n");
return fmt;
}
// cpu_timer ---------------------------------------------------------------------//
void cpu_timer::start()
{
m_is_stopped = false;
get_cpu_times(m_times);
}
const cpu_times& cpu_timer::stop()
{
if (is_stopped())
return m_times;
m_is_stopped = true;
cpu_times current;
get_cpu_times(current);
m_times.wall = (current.wall - m_times.wall);
m_times.user = (current.user - m_times.user);
m_times.system = (current.system - m_times.system);
return m_times;
}
cpu_times cpu_timer::elapsed() const
{
if (is_stopped())
return m_times;
cpu_times current;
get_cpu_times(current);
current.wall -= m_times.wall;
current.user -= m_times.user;
current.system -= m_times.system;
return current;
}
void cpu_timer::resume()
{
if (is_stopped())
{
cpu_times current (m_times);
start();
m_times.wall -= current.wall;
m_times.user -= current.user;
m_times.system -= current.system;
}
}
} // namespace timer
} // namespace boost

View File

@@ -1,9 +1,39 @@
#~ Copyright Rene Rivera 2008
#~ Distributed under the Boost Software License, Version 1.0.
#~ (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
# Boost Timer Library test Jamfile
import testing ;
# Copyright Beman Dawes 2003, 2006, 2011
test-suite timer
: [ compile timer_test.cpp ]
# Distributed under the Boost Software License, Version 1.0.
# See http://www.boost.org/LICENSE_1_0.txt
# See library home page at http://www.boost.org/libs/timer
project
: requirements
<library>/boost/timer//boost_timer
<toolset>msvc:<asynch-exceptions>on
;
test-suite "timer"
:
[ run ../example/auto_cpu_timer_example.cpp
: # command line
: # input files
: <test-info>always_show_run_output # requirements
]
[ run cpu_timer_info.cpp
: # command line
: # input files
: <test-info>always_show_run_output # requirements
]
[ run cpu_timer_test.cpp
: # command line
: # input files
: <test-info>always_show_run_output # requirements
]
[ run ../example/timex.cpp
: echo "Hello, world"
:
: <test-info>always_show_run_output
]
[ compile original_timer_test.cpp ]
;

75
test/cpu_timer_info.cpp Normal file
View File

@@ -0,0 +1,75 @@
// boost cpu_timer_info.cpp ----------------------------------------------------------//
// Copyright Beman Dawes 2011
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
// See http://www.boost.org/libs/timer for documentation.
#include <boost/timer/timer.hpp>
#include <boost/chrono/chrono.hpp>
#include <boost/detail/lightweight_main.hpp>
#include <cstdlib> // for atol()
#include <iostream>
#include <locale>
using boost::timer::nanosecond_type;
using boost::timer::cpu_times;
using boost::timer::cpu_timer;
using boost::timer::auto_cpu_timer;
using std::cout; using std::endl;
int cpp_main( int argc, char * argv[] )
{
cout << '\n';
cout << "For cpu_times.wall, the underlying clock "
<< (boost::chrono::high_resolution_clock::is_steady
? "is steady. "
: "is not steady. "
)
<< "Steady clocks are defined by C++11 as clocks for which values "
"of time_point never decrease as physical time advances and for "
"which values of time_point advance at a steady rate relative to "
"real time. That is, the clock may not be adjusted.\n\n";
cpu_times start_time;
start_time.clear();
cpu_times current_time;
{
cpu_timer cpu;
cout << "measure boost::timer::cpu_timer resolution for user time..."
<< endl;
for (int i = 0; i < 3; ++i)
{
cpu.start();
start_time = cpu.elapsed();
current_time.user = start_time.user;
while (current_time.user == start_time.user)
{
current_time = cpu.elapsed();
}
cout << current_time.user - start_time.user << "ns\n";
}
}
{
cpu_timer cpu;
cout << "measure boost::timer::cpu_timer resolution for wall-clock time..."
<< endl;
for (int i = 0; i < 100; ++i)
{
cpu.start();
start_time.wall = cpu.elapsed().wall;
current_time.wall = start_time.wall;
while (current_time.wall == start_time.wall)
{
current_time.wall = cpu.elapsed().wall;
}
cout << current_time.wall - start_time.wall << "ns ";
}
}
return 0;
}

133
test/cpu_timer_test.cpp Normal file
View File

@@ -0,0 +1,133 @@
// boost timer_test.cpp --------------------------------------------------------------//
// Copyright Beman Dawes 2006, 2011
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
// See http://www.boost.org/libs/timer for documentation.
#include <boost/timer/timer.hpp>
#include <boost/detail/lightweight_main.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <cstdlib> // for atol()
#include <iostream>
#include <string>
namespace old
{
#include <boost/timer.hpp>
}
using std::string;
using std::cout;
using std::endl;
using boost::timer::nanosecond_type;
using boost::timer::cpu_times;
using boost::timer::format;
using boost::timer::cpu_timer;
using boost::timer::auto_cpu_timer;
namespace
{
void format_test()
{
cout << "format test..." << endl;
cpu_times times;
times.wall = 5123456789LL;
times.user = 2123456789LL;
times.system = 1234567890LL;
cout << " times.wall is " << times.wall << '\n';
cout << " times.user is " << times.user << '\n';
cout << " times.system is " << times.system << '\n';
cout << " user+system is " << times.user + times.system << '\n';
cout << " format(times, 9) output: " << format(times, 9);
BOOST_TEST_EQ(format(times, 9),
string(" 5.123456789s wall, 2.123456789s user + 1.234567890s system = 3.358024679s CPU (65.5%)\n"));
BOOST_TEST_EQ(format(times, 8),
string(" 5.12345679s wall, 2.12345679s user + 1.23456789s system = 3.35802468s CPU (65.5%)\n"));
BOOST_TEST_EQ(format(times, 7),
string(" 5.1234568s wall, 2.1234568s user + 1.2345679s system = 3.3580247s CPU (65.5%)\n"));
BOOST_TEST_EQ(format(times, 6),
string(" 5.123457s wall, 2.123457s user + 1.234568s system = 3.358025s CPU (65.5%)\n"));
BOOST_TEST_EQ(format(times, 5),
string(" 5.12346s wall, 2.12346s user + 1.23457s system = 3.35802s CPU (65.5%)\n"));
BOOST_TEST_EQ(format(times, 4),
string(" 5.1235s wall, 2.1235s user + 1.2346s system = 3.3580s CPU (65.5%)\n"));
BOOST_TEST_EQ(format(times, 3),
string(" 5.123s wall, 2.123s user + 1.235s system = 3.358s CPU (65.5%)\n"));
BOOST_TEST_EQ(format(times, 2),
string(" 5.12s wall, 2.12s user + 1.23s system = 3.36s CPU (65.5%)\n"));
BOOST_TEST_EQ(format(times, 1),
string(" 5.1s wall, 2.1s user + 1.2s system = 3.4s CPU (65.5%)\n"));
BOOST_TEST_EQ(format(times, 0),
string(" 5s wall, 2s user + 1s system = 3s CPU (65.5%)\n"));
BOOST_TEST_EQ(format(times, 10),
string(" 5.123456789s wall, 2.123456789s user + 1.234567890s system = 3.358024679s CPU (65.5%)\n"));
BOOST_TEST_EQ(format(times, -1),
string(" 5.123457s wall, 2.123457s user + 1.234568s system = 3.358025s CPU (65.5%)\n"));
BOOST_TEST_EQ(format(times),
string(" 5.123457s wall, 2.123457s user + 1.234568s system = 3.358025s CPU (65.5%)\n"));
BOOST_TEST_EQ(format(times, 5, " %w, %u, %s, %t, %%p%"),
string(" 5.12346, 2.12346, 1.23457, 3.35802, %65.5%"));
BOOST_TEST_EQ(format(times, 5, "boo"), string("boo"));
cout << " format test complete" << endl;
}
void std_c_consistency_test()
{
cout << "C library consistency test..." << endl;
// This test is designed to account for C timer resolution and for the possibility
// that another active process may take up a lot of time.
cout << " CLOCKS_PER_SEC is " << CLOCKS_PER_SEC << endl;
double c_t_elapsed;
old::boost::timer c_t;
cpu_timer t;
while (t.elapsed().wall < 1000000000) {}
t.stop();
c_t_elapsed = c_t.elapsed();
cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
cout.precision(9);
cout << " c_t_elapsed is " << c_t_elapsed << endl;
cout << " t.elapsed().wall is " << t.elapsed().wall << endl;
cout << " t.elapsed().wall/1000000000.0L is "
<< t.elapsed().wall/1000000000.0L << endl;
cout << " c_t_elapsed * 1.05L is "
<< c_t_elapsed * 1.05L << endl;
BOOST_TEST(t.elapsed().wall >= 1000000000);
BOOST_TEST(t.elapsed().wall / 1000000000.0L <= c_t_elapsed * 1.05L);
cout << " C library consistency test complete" << endl;
}
} // unnamed namespace
//--------------------------------------------------------------------------------------//
int cpp_main(int argc, char * argv[])
{
cout << "---------- timer_test ----------\n";
format_test();
std_c_consistency_test();
return ::boost::report_errors();
}