]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | <html> |
2 | ||
3 | <head> | |
4 | <meta http-equiv="Content-Language" content="en-us"> | |
5 | <meta name="GENERATOR" content="Microsoft FrontPage 5.0"> | |
6 | <meta name="ProgId" content="FrontPage.Editor.Document"> | |
7 | <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> | |
8 | <title>CPU Timers</title> | |
9 | <style type="text/css"> | |
10 | ins {background-color:#A0FFA0} | |
11 | del {background-color:#FFA0A0} | |
12 | body | |
13 | { | |
14 | font-family: sans-serif; | |
15 | max-width : 8.5in; | |
16 | margin: 1em; | |
17 | } | |
18 | </style> | |
19 | </head> | |
20 | ||
21 | <body> | |
22 | ||
23 | <table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="750"> | |
24 | <tr> | |
25 | <td width="300"> | |
26 | <a href="../../../index.htm"> | |
27 | <img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="300" height="86" border="0"></a></td> | |
28 | <td align="middle" width="430"> | |
29 | <font size="7">Timer Library<br> | |
30 | CPU Timers</font></td> | |
31 | </tr> | |
32 | </table> | |
33 | ||
34 | <table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF" width="100%"> | |
35 | <tr> | |
36 | <td><a href="index.html">Timer Home</a> | |
37 | <a href="cpu_timers.html">CPU timers</a> | |
38 | <a href="original_timer.html">Original timers</a> | |
39 | </td> | |
40 | </tr> | |
41 | </table> | |
42 | ||
43 | <h2><a name="Introduction">Introduction</a></h2> | |
44 | <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" align="right"> | |
45 | <tr> | |
46 | <td width="100%" bgcolor="#D7EEFF" align="center"> | |
47 | <i><b>Contents</b></i></td> | |
48 | </tr> | |
49 | <tr> | |
50 | <td width="100%" bgcolor="#E8F5FF"> | |
51 | <a href="#Introduction">Introduction</a><br> | |
52 | <a href="#Example">Using the timers</a><br> | |
53 | <a href="#using-auto_cpu_timer">Using <code>auto_cpu_timer</code></a><br> | |
54 | <a href="#using-cpu_timer">Using <code>cpu_timer</code></a><br> | |
55 | <a href="#Timer-accuracy">Timer accuracy</a><br> | |
56 | <a href="#Resolution">Resolution</a><br> | |
57 | <a href="#Other-concerns">Other concerns</a><br> | |
58 | <a href="#Recommendations">Recommendations</a><br> | |
59 | <a href="#Reference">Reference</a><br> | |
60 | <code> <a href="#Synopsis"><boost/timer/timer.hpp></a></code><a href="#Synopsis"> | |
61 | synopsis</a><br> | |
62 | <a href="#Default-format">Default format</a><br> | |
63 | <a href="#nanosecond_type">Typedef <code>nanosecond_type</code></a><br> | |
64 | <a href="#Namespace-scope-functions">Namespace scope functions</a><br> | |
65 | <a href="#format"><code>format()</code></a><br> | |
66 | | |
67 | <a href="#Class-cpu_timer">Class <code>cpu_timer</code></a><br> | |
68 | <code> <a href="#cpu_timer-constructors">cpu_timer</a></code><a href="#cpu_timer-constructors"> | |
69 | constructors, destructor</a><br> | |
70 | <code><a href="#cpu_timer-observers">cpu_timer</a></code><a href="#cpu_timer-observers"> | |
71 | observers</a><br> | |
72 | <code> <a href="#cpu_timer-actions">cpu_timer</a></code><a href="#cpu_timer-actions"> | |
73 | actions</a><br> | |
74 | <a href="#Class-auto_cpu_timer">Class <code>auto_cpu_timer</code></a><br> | |
75 | <code> <a href="#auto_cpu_timer-constructors">auto_cpu_timer</a></code><a href="#auto_cpu_timer-constructors"> constructors</a><br> | |
76 | <code> <a href="#auto_cpu_timer-destructor">auto_cpu_timer</a></code><a href="#auto_cpu_timer-destructor"> destructor</a><br> | |
77 | <a href="#auto_cpu_timer-observers"><code> | |
78 | auto_cpu_timer</code> observers</a><br> | |
79 | <code> <a href="#auto_cpu_timer-actions">auto_cpu_timer</a></code><a href="#auto_cpu_timer-actions"> actions</a><br> | |
80 | <a href="#History">History</a><br> | |
81 | <a href="#Acknowledgements">Acknowledgements</a></tr> | |
82 | </table> | |
83 | ||
84 | <p>Knowing how long a program takes to execute is useful in both test and | |
85 | production environments. It may also be helpful if such timing information is broken down | |
86 | into wall clock time, CPU time spent by the user, and CPU time spent by the | |
87 | operating system servicing user requests.</p> | |
88 | ||
89 | <p>Class <code><a href="#Class-cpu_timer">cpu_timer</a></code> measures | |
90 | wall clock time, user CPU process time, and system CPU process time. Class <code> | |
91 | <a href="#Class-auto_cpu_timer">auto_cpu_timer</a></code> is a refinement of | |
92 | <code>cpu_timer</code> that automatically reports the elapsed times when an <code> | |
93 | auto_cpu_timer</code> object is destroyed.</p> | |
94 | ||
95 | <h2><a name="Setup">Setup</a></h2> | |
96 | ||
97 | <p>Boost.Timer is implemented as a separately compiled library, so you must | |
98 | install binaries in a location that can be found by your linker. If you followed | |
99 | the | |
100 | <a href="http://www.boost.org/doc/libs/release/more/getting_started/index.html"> | |
101 | Boost Getting Started</a> instructions, that's already done for you.</p> | |
102 | ||
103 | <h2><a name="Example">Using the timers</a></h2> | |
104 | ||
105 | <h3>Using <code><a name="using-auto_cpu_timer">auto_cpu_timer</a></code></h3> | |
106 | ||
107 | <p>The simplest and most common use is to add the two lines highlighted below | |
108 | to a scope you want to time. See <code> | |
109 | <a href="../example/auto_cpu_example.cpp">auto_cpu_timer_example.cpp</a></code> | |
110 | for the source code. </p> | |
111 | <blockquote> | |
112 | <pre><span style="background-color: #D7EEFF">#include <boost/timer/</span><span style="background-color: #D7EEFF">timer.hpp</span><span style="background-color: #D7EEFF">></span> | |
113 | #include <cmath> | |
114 | ||
115 | int main() | |
116 | { | |
117 | <span style="background-color: #D7EEFF">boost::timer::auto_cpu_timer</span><span style="background-color: #D7EEFF"> t;</span> | |
118 | ||
119 | for (long i = 0; i < 100000000; ++i) | |
120 | std::sqrt(123.456L); // burn some time | |
121 | ||
122 | return 0; | |
123 | }</pre> | |
124 | </blockquote> | |
125 | <p>When the <code>auto_cpu_timer</code> object is created, it starts timing. When | |
126 | it is destroyed at the end of the scope, its destructor stops the timer and | |
127 | displays timing information on the default output stream, <code>std::cout</code>.</p> | |
128 | <p>The output of this program will look something like this:</p> | |
129 | <p><code> 5.713010s wall, 5.709637s user + 0.000000s system = | |
130 | 5.709637s CPU (99.9%)</code></p> | |
131 | <p>In other words, this program ran in <code>5.713010</code> seconds as would be measured by a | |
132 | clock on the wall, the operating system charged it for <code>5.709637</code> seconds of user CPU | |
133 | time and 0 seconds of system CPU time, the total of these two was <code>5.709637</code>, and that | |
134 | represented <code>99.9</code> percent of the wall clock time.</p> | |
135 | ||
136 | <p>The output stream, number of decimal places reported, and reporting format | |
137 | can be controlled by <code>auto_cpu_timer</code> constructor arguments. Here is | |
138 | what the output from the above program would look like for several different | |
139 | sets of constructor arguments:</p> | |
140 | ||
141 | <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> | |
142 | <tr> | |
143 | <td><i><b>Construction</b></i></td> | |
144 | <td><i><b>Output</b></i></td> | |
145 | </tr> | |
146 | <tr> | |
147 | <td><code><font size="1">t</font></code></td> | |
148 | <td><code><font size="1">5.713010s wall, 5.709637s user + 0.000000s system = 5.709637s | |
149 | CPU (99.9%)</font></code></td> | |
150 | </tr> | |
151 | <tr> | |
152 | <td><code><font size="1">t(std::cerr</font><font size="1">, 2)</font></code></td> | |
153 | <td><code><font size="1">5.71s wall, 5.70s user + 0.00s system = 5.70s CPU (99.9%)</font></code></td> | |
154 | </tr> | |
155 | <tr> | |
156 | <td><code><font size="1">t(1)</font></code></td> | |
157 | <td><code><font size="1">5.7s wall, 5.7s user + 0.0s system = 5.7s CPU (99.9%)</font></code></td> | |
158 | </tr> | |
159 | <tr> | |
160 | <td><code><font size="1">t(3, "%w seconds\n")</font></code></td> | |
161 | <td><code><font size="1">5.713 seconds<br> | |
162 | </font></code></td> | |
163 | </tr> | |
164 | <tr> | |
165 | <td><code><font size="1">t("%t</font><font size="1"> sec CPU, %w sec real") | |
166 | </font> </code></td> | |
167 | <td><code><font size="1">5.709637 sec CPU, 5.713010 sec real</font></code></td> | |
168 | </tr> | |
169 | </table> | |
170 | <p> The processing of the format string is described <a href="#format">here</a>.</p> | |
171 | <h3> Using <code><a name="using-cpu_timer">cpu_timer</a></code></h3> | |
172 | <p> The following code creates a checkpoint every 20 CPU seconds:</p> | |
173 | <blockquote> | |
174 | <pre>using boost::timer::cpu_timer; | |
175 | using boost::timer::cpu_times; | |
176 | using boost::timer::nanosecond_type; | |
177 | ... | |
178 | nanosecond_type const twenty_seconds(20 * 1000000000LL); | |
179 | nanosecond_type last(0); | |
180 | cpu_timer timer; | |
181 | while (more_transactions) | |
182 | { | |
183 | process_a_transaction(); | |
184 | cpu_times const elapsed_times(timer.elapsed()); | |
185 | nanosecond_type const elapsed(elapsed_times.system | |
186 | + elapsed_times.user); | |
187 | if (elapsed >= twenty_seconds) | |
188 | { | |
189 | ... create a checkpoint ... | |
190 | last = elapsed; | |
191 | } | |
192 | }</pre> | |
193 | </blockquote> | |
194 | ||
195 | <h2><a name="Timer-accuracy">Timer accuracy</a></h2> | |
196 | ||
197 | <p>How accurate are these timers? </p> | |
198 | ||
199 | <h3><a name="Resolution">Resolution</a></h3> | |
200 | ||
201 | <p dir="ltr">The resolution of a clock, and thus timers built on that clock, | |
202 | is the minimum period time that can be measured. The program <code> | |
203 | <a href="../test/cpu_timer_info.cpp">cpu_timer_info.cpp</a></code> measures | |
204 | the resolution of <code>cpu_timer</code>.</p> | |
205 | ||
206 | <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> | |
207 | <tr> | |
208 | <td rowspan="2" bgcolor="#D7EEFF">O/S</td> | |
209 | <td rowspan="2" bgcolor="#D7EEFF">Processor</td> | |
210 | <td colspan="2" align="center" bgcolor="#D7EEFF">Wall-clock</td> | |
211 | <td colspan="2" align="center" bgcolor="#D7EEFF">CPU</td> | |
212 | </tr> | |
213 | <tr> | |
214 | <td bgcolor="#D7EEFF">Resolution</td> | |
215 | <td bgcolor="#D7EEFF">Comments</td> | |
216 | <td align="center" bgcolor="#D7EEFF">User<br> | |
217 | Resolution</td> | |
218 | <td align="center" bgcolor="#D7EEFF">System<br> | |
219 | Resolution</td> | |
220 | </tr> | |
221 | <tr> | |
222 | <td>Mac OS X Lion</td> | |
223 | <td>Intel circa 2007</td> | |
224 | <td align="right">2100ns<br> | |
225 | 2200ns</td> | |
226 | <td>Some variation within a range.</td> | |
227 | <td>10000000ns</td> | |
228 | <td>10000000ns</td> | |
229 | </tr> | |
230 | <tr> | |
231 | <td>Ubuntu Linux 11.4</td> | |
232 | <td>Intel circa 2005</td> | |
233 | <td align="right">516ns</td> | |
234 | <td>Very little variation, typically less than 5ns </td> | |
235 | <td>10000000ns</td> | |
236 | <td>10000000ns</td> | |
237 | </tr> | |
238 | <tr> | |
239 | <td>Windows 7</td> | |
240 | <td>Intel Core i7 860 @ 2.9 GHz</td> | |
241 | <td align="right">366ns</td> | |
242 | <td>Some variation, usually in multiples of 366ns</td> | |
243 | <td>15600100ns</td> | |
244 | <td>15600100ns</td> | |
245 | </tr> | |
246 | <tr> | |
247 | <td>Windows 7</td> | |
248 | <td>Intel Mobile T7200 @ 2.0 GHz</td> | |
249 | <td align="right">2050ns</td> | |
250 | <td>Much variation. Resolution degrades when processor slows, probably due | |
251 | to known chipset errata. </td> | |
252 | <td>15600100ns</td> | |
253 | <td>15600100ns</td> | |
254 | </tr> | |
255 | <tr> | |
256 | <td>Windows XP</td> | |
257 | <td>Intel Atom N2800 @ 1.0 GHz</td> | |
258 | <td align="right">1437ns</td> | |
259 | <td>Some variation.</td> | |
260 | <td>15625000ns</td> | |
261 | <td>15625000ns</td> | |
262 | </tr> | |
263 | </table> | |
264 | ||
265 | <h3><a name="Other-concerns">Other concerns</a></h3> | |
266 | ||
267 | <p>Wall-clock timings are subject to many outside influences, such as the impact | |
268 | of other processes.</p> | |
269 | ||
270 | <blockquote> | |
271 | ||
272 | <p><code>cpu_timer</code> and <code>auto_cpu_timer</code> obtain Wall-clock | |
273 | timings from Boost.Chrono's <code>high_resolution_clock</code>. On Intel | |
274 | compatible CPU's running Windows, Linux, and Mac OS X, this is a "steady | |
275 | clock" [C++11 20.11.3], but may not be steady on other platforms. <code> | |
276 | <a href="../test/cpu_timer_info.cpp">cpu_timer_info.cpp</a></code> reports | |
277 | whether or not the <code>high_resolution_clock</code> is steady on a | |
278 | particular platform.</p> | |
279 | ||
280 | <p><i><b><a name="Steady-clocks">Steady clocks</a></b></i> are defined by the | |
281 | C++11 standard as clocks for which values never decrease as physical time | |
282 | advances and for which values advance at a steady rate relative to real time. | |
283 | That is, the clock may not be adjusted. Clocks that are steady never run | |
284 | backwards, even when the operating system's clock is reset backwards such as | |
285 | during a daylight saving time transition.</p> | |
286 | ||
287 | </blockquote> | |
288 | ||
289 | <p>Timings of debug builds are often several times slower | |
290 | than release builds, because compiler optimization is turned off and | |
291 | because libraries often supply very expensive error checks on debug builds.</p> | |
292 | ||
293 | <p>Synthetic benchmark code may be optimized way, particularly if NDEBUG is | |
294 | defined. It may be | |
295 | necessary to inspect generated code to verify this isn't happening.</p> | |
296 | ||
297 | <h3 dir="ltr"><a name="Recommendations">Recommendations</a></h3> | |
298 | ||
299 | <p dir="ltr">Think about what is important to your application. For a | |
300 | production process, the wall clock time may be what is most important. To | |
301 | study the efficiency of code, total CPU time (user + system) is often a much better measure.</p> | |
302 | ||
303 | <p dir="ltr">A useful recommendation is to never trust timings unless they are | |
304 | (1) at least 100 times longer than the CPU time resolution, (2) run multiple | |
305 | times, and (3) run on release builds. And results that are too good to be true | |
306 | need to be should be investigated skeptically.</p> | |
307 | ||
308 | <p>Shared libraries (DLLs and .so's) may incur extra time delays, including expensive | |
309 | disk accesses, the first time a timer or other function is called. If that | |
310 | would be misleading, static linking should be considered.</p> | |
311 | ||
312 | <h2> <a name="Reference">Reference</a></h2> | |
313 | <p> Specifications are given in the style of the C++ standard library (C++11, | |
314 | 17.5.1.4 [structure.specifications]). An additional <i>Overview</i> element may | |
315 | be provided to aid understanding. <i>Overview</i> elements are only informative | |
316 | - actual semantics are given by the other detailed specification elements.</p> | |
317 | <p dir="ltr"> Functions not specified as <code>noexcept</code> will throw <code> | |
318 | std::bad_alloc</code> exceptions if a memory allocation error occurs. Other | |
319 | errors are reported by time values of -1. [<i>Note:</i> Modern hardware and | |
320 | operating systems have robust clock subsystems, so such errors are unusual if | |
321 | even possible at all. <i>-- end note</i>]</p> | |
322 | <p dir="ltr"> The Timer library meets the same data race avoidance requirements | |
323 | as the C++11 standard library (17.6.5.9 [res.on.data.races]). Shared objects of | |
324 | Timer library types risk undefined behavior unless the user supplies a locking | |
325 | mechanism. See C++11, 17.6.4.10 [res.on.objects], <i>Shared objects and the | |
326 | library</i>. </p> | |
327 | <h3> | |
328 | <code><boost/timer/timer.hpp></code> <a name="Synopsis">synopsis</a></h3> | |
329 | <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%"> | |
330 | <tr> | |
331 | <td bgcolor="#D7EEFF"> | |
332 | <blockquote> | |
333 | <pre>namespace boost | |
334 | { | |
335 | namespace timer | |
336 | { | |
337 | class <a href="#Class-cpu_timer">cpu_timer</a>; // wall clock, user, and system timer | |
338 | class <a href="#Class-auto_cpu_timer">auto_cpu_timer</a>; // automatic report() on destruction | |
339 | ||
340 | typedef boost::int_least64_t nanosecond_type; | |
341 | ||
342 | struct cpu_times | |
343 | { | |
344 | nanosecond_type wall; | |
345 | nanosecond_type user; | |
346 | nanosecond_type system; | |
347 | ||
348 | void clear(); | |
349 | }; | |
350 | ||
351 | const int <a name="default_places">default_places</a> = 6; | |
352 | ||
353 | std::string format(const cpu_times& times, short places, const std::string& format); | |
354 | std::string format(const cpu_times& times, short places = default_places); | |
355 | ||
356 | } // namespace timer | |
357 | } // namespace boost</pre> | |
358 | </blockquote> | |
359 | </td> | |
360 | </tr> | |
361 | </table> | |
362 | ||
363 | <h3><a name="Default-format">Default format</a></h3> | |
364 | ||
365 | <p>The default format is " %ws wall, %us user + %ss system = %ts CPU (%p%)\n".</p> | |
366 | ||
367 | <h3>Typedef <a name="nanosecond_type"><code>nanosecond_type</code></a></h3> | |
368 | ||
369 | <p>The typedef <code>nanosecond_type</code> provides an implementation defined type capable | |
370 | of representing nanoseconds. For POSIX and Windows systems, <code> | |
371 | nanoseconds_type</code> is <code>boost::int_least64_t</code>.</p> | |
372 | ||
373 | <p>The underlying type is not based on the Boost Date-Time or Chrono library to avoid a | |
374 | dependency on a large library. This design choice may change at some future | |
375 | date.</p> | |
376 | ||
377 | <p>Although <code>nanosecond_type</code> is capable of representing one <b> | |
378 | nanosecond</b>, the actual resolution of common operating system timers may be | |
379 | much lower. For wall clock time on desktop systems circa 2010, resolution is | |
380 | often no better than than one <b>microsecond</b>. For user and system time, typical | |
381 | resolution is 15 <b>milliseconds</b> on Windows and 10 <b>milliseconds</b> on | |
382 | POSIX.</p> | |
383 | ||
384 | <h3><a name="cpu_times">Struct <code>cpu_times</code></a></h3> | |
385 | ||
386 | <p>Struct <code>cpu_times</code> packages the elapsed wall clock time, user | |
387 | process CPU time, and system process CPU time. See | |
388 | <a href="#Current-time-values">Current time values</a> for definitions of the | |
389 | source of these elapsed times.</p> | |
390 | ||
391 | <pre><span style="background-color: #D7EEFF">void clear();</span></pre> | |
392 | <blockquote> | |
393 | <p><i>Effects:</i> <code>wall = user = system = 0LL</code>.</p> | |
394 | </blockquote> | |
395 | ||
396 | <h3><a name="Namespace-scope-functions">Namespace scope functions</a></h3> | |
397 | ||
398 | <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><a href="#cpu_times"><span style="background-color: #D7EEFF">cpu_times</span></a><span style="background-color: #D7EEFF">& times, short places, const std::string& format); | |
399 | std::string </span><a name="format"><span style="background-color: #D7EEFF">format</span></a><span style="background-color: #D7EEFF">(const </span><a href="#cpu_times"><span style="background-color: #D7EEFF">cpu_times</span></a><span style="background-color: #D7EEFF">& times, short places = default_places);</span></pre> | |
400 | <blockquote> | |
401 | ||
402 | <p><i>Overview: </i>Converts <code>times</code>'s values to strings representing | |
403 | seconds to <code>places</code> decimal places, and inserts them into the return | |
404 | string as controlled by <code>format</code>.</p> | |
405 | ||
406 | <p><i>Remarks:</i> For the overload without the <code>format</code> | |
407 | argument, the <a href="#Default-format">default format</a> is used as <code>format</code>.</p> | |
408 | ||
409 | <p><i>Returns:</i> A string that is a copy of <code>format</code>, except that any | |
410 | instances of the sequences shown below are replaced by the indicated value. | |
411 | Times are reported in seconds, | |
412 | shown to <code>std::max(0, std::min(default_places, 9))</code> decimal places. Percentage is reported to one | |
413 | decimal place. [<i>Note:</i> percentage may exceed 100% due to differences in | |
414 | how operating systems measure various times. <i>--end note</i>]</p> | |
415 | ||
416 | <p><i><b><a name="Format-replacement-sequences">Format replacement sequences</a></b></i></p> | |
417 | ||
418 | <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111"> | |
419 | <tr> | |
420 | <td align="center" bgcolor="#D7EEFF"><b><i>Sequence</i></b></td> | |
421 | <td align="center" bgcolor="#D7EEFF"><b><i>Replacement value</i></b></td> | |
422 | </tr> | |
423 | <tr> | |
424 | <td align="center"><code>%w</code></td> | |
425 | <td><code>times.wall</code></td> | |
426 | </tr> | |
427 | <tr> | |
428 | <td align="center"><code>%u</code></td> | |
429 | <td><code>times.user</code></td> | |
430 | </tr> | |
431 | <tr> | |
432 | <td align="center"><code>%s</code></td> | |
433 | <td><code>times.system</code></td> | |
434 | </tr> | |
435 | <tr> | |
436 | <td align="center"><code>%t</code></td> | |
437 | <td><code>times.user + times.system</code></td> | |
438 | </tr> | |
439 | <tr> | |
440 | <td align="center"><code>%p</code></td> | |
441 | <td>The percentage of <code>times.wall</code> represented by <code> | |
442 | times.user + times.system</code></td> | |
443 | </tr> | |
444 | </table> | |
445 | </blockquote> | |
446 | ||
447 | <h3><a name="Class-cpu_timer">Class <code>cpu_timer</code></a></h3> | |
448 | ||
449 | <p> <code>cpu_timer</code> objects measure wall clock elapsed time and process elapsed | |
450 | time charged to the user and system.</p> | |
451 | ||
452 | <p><i><b><a name="Current-time-values">Current time values</a></b></i> are the | |
453 | current wall clock time, user process time, and system process time as provided | |
454 | by the operating system:</p> | |
455 | ||
456 | <ul> | |
457 | <li>Wall clock time is time as would be measured by | |
458 | an ordinary wristwatch or clock on the wall.</li> | |
459 | <li>User process time is "the CPU time charged for the | |
460 | execution of user instructions of the calling process." See | |
461 | <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/times.html"> | |
462 | POSIX</a>.</li> | |
463 | <li>System process time is "the CPU time charged for | |
464 | execution by the system on behalf of the calling process." See | |
465 | <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/times.html"> | |
466 | POSIX</a>.</li> | |
467 | </ul> | |
468 | ||
469 | <h3> <a name="cpu_timer-synopsis"> <code>cpu_timer</code> synopsis</a></h3> | |
470 | ||
471 | <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%"> | |
472 | <tr> | |
473 | <td bgcolor="#D7EEFF"> | |
474 | ||
475 | <pre> | |
476 | class <a name="cpu_timer">cpu_timer</a> | |
477 | { | |
478 | public: | |
479 | ||
480 | // constructor | |
481 | <a href="#cpu_timer-ctor">cpu_timer</a>() noexcept; | |
482 | ||
483 | // compiler generated; shown for exposition only | |
484 | ~cpu_timer() noexcept = default; | |
485 | cpu_timer(const cpu_timer&) noexcept = default; | |
486 | cpu_timer& operator=(const cpu_timer&) noexcept = default; | |
487 | ||
488 | // observers | |
489 | bool <a href="#is_stopped">is_stopped</a>() const noexcept; | |
490 | cpu_times <a href="#elapsed">elapsed</a>() const noexcept; | |
491 | std::string <a href="#cpu_timer-format">format</a>(int places, const std::string& format) const; | |
492 | std::string <a href="#cpu_timer-format">format</a>(int places = default_places) const; | |
493 | ||
494 | // actions | |
495 | void <a href="#start">start</a>() noexcept; | |
496 | void <a href="#stop">stop</a>() noexcept; | |
497 | void <a href="#resume">resume</a>() noexcept; | |
498 | };</pre> | |
499 | </td> | |
500 | </tr> | |
501 | </table> | |
502 | <h3><a name="cpu_timer-constructors"><code>cpu_timer</code> constructor</a></h3> | |
503 | <pre><span style="background-color: #D7EEFF"><a name="cpu_timer-ctor">cpu_timer</a>() noexcept;</span></pre> | |
504 | <blockquote> | |
505 | <p><i>Effects:</i> Constructs an object of type <code> | |
506 | cpu_timer</code>. Calls<code> start()</code>.</p> | |
507 | </blockquote> | |
508 | <h3><a name="cpu_timer-observers"><code>cpu_timer</code> | |
509 | observers</a></h3> | |
510 | <pre><span style="background-color: #D7EEFF">bool</span><span style="background-color: #D7EEFF"> <a name="is_stopped">is_stopped</a>() const noexcept;</span></pre> | |
511 | <blockquote> | |
512 | <p><i>Returns:</i> <code>true</code> if <a href="#stop">stop()</a> was the most recent | |
513 | <a href="#cpu_timer-actions">action</a> function called, | |
514 | otherwise <code>false</code>.</p> | |
515 | </blockquote> | |
516 | <pre><span style="background-color: #D7EEFF">cpu_times</span><span style="background-color: #D7EEFF"> <a name="elapsed">elapsed</a>() const noexcept;</span></pre> | |
517 | <blockquote> | |
518 | ||
519 | <p><i>Returns:</i> If <code>is_stopped()</code>, the accumulated elapsed times | |
520 | as of the previous <a href="#stop">stop()</a>. Otherwise, the elapsed times | |
521 | accumulated between the most recent call to <a href="#start">start()</a> or | |
522 | <a href="#resume">resume()</a> and the <a href="#Current-time-values">current | |
523 | time values</a>.</p> | |
524 | ||
525 | </blockquote> | |
526 | <pre><span style="background-color: #D7EEFF">std::string </span><a href="#cpu_timer-format"><span style="background-color: #D7EEFF">format</span></a><span style="background-color: #D7EEFF">(int</span><span style="background-color: #D7EEFF"> places, const std::string& format) const; | |
527 | std::string </span><a href="#cpu_timer-format"><span style="background-color: #D7EEFF">format</span></a><span style="background-color: #D7EEFF">(int</span><span style="background-color: #D7EEFF"> places = </span><span style="background-color: #D7EEFF">default_places</span><span style="background-color: #D7EEFF">) const;</span></pre> | |
528 | <blockquote> | |
529 | <p><i>Overview:</i> Returns a string for the current elapsed time as formatted | |
530 | by the <a href="#format">format non-member function</a>.</p> | |
531 | <p><i>Returns:</i> <code>boost::<a href="#format">timer::format</a>(<a href="#elapsed">elapsed</a>(), places<i>[, format]</i>)</code>.</p> | |
532 | </blockquote> | |
533 | <h3><a name="cpu_timer-actions"><code>cpu_timer</code> | |
534 | actions</a></h3> | |
535 | <pre><span style="background-color: #D7EEFF">void <a name="start">start</a>() noexcept;</span></pre> | |
536 | <blockquote> | |
537 | ||
538 | <p dir="ltr"><i>Effects:</i> Begins accumulating elapsed time as of the <a href="#Current-time-values">current time values</a>.</p> | |
539 | ||
540 | <p><i>Postconditions:</i> <code>!is_stopped()</code>.</p> | |
541 | ||
542 | </blockquote> | |
543 | <pre><span style="background-color: #D7EEFF">void <a name="stop">stop</a>() noexcept;</span></pre> | |
544 | <blockquote> | |
545 | ||
546 | <p><i>Effects:</i> If <code>!is_stopped()</code>, stops accumulating elapsed | |
547 | time as of the <a href="#Current-time-values">current time values</a>.</p> | |
548 | ||
549 | <blockquote> | |
550 | ||
551 | <p>[<i>Note:</i> This is observable via <code>elapsed()</code>. <i>-- end note</i>]</p> | |
552 | ||
553 | </blockquote> | |
554 | ||
555 | <p><i>Postconditions:</i> <code>is_stopped()</code>.</p> | |
556 | ||
557 | </blockquote> | |
558 | <pre><span style="background-color: #D7EEFF">void <a name="resume">resume</a>() noexcept;</span></pre> | |
559 | <blockquote> | |
560 | <p><i>Overview:</i> Restarts the timer, accumulating additional elapsed time.</p> | |
561 | <p><i>Effects:</i> If <code>is_stopped()</code>, resumes accumulating | |
562 | additional elapsed time, as of the <a href="#Current-time-values">current time values</a>. Otherwise, no effect.</p> | |
563 | </blockquote> | |
564 | <h3><a name="Class-auto_cpu_timer">Class <code>auto_cpu_timer</code></a></h3> | |
565 | ||
566 | <p>Class <code>auto_cpu_timer</code> adds a <code>report()</code> | |
567 | function to <code>class cpu_timer</code>, and automatically calls <code>report()</code> | |
568 | on destruction.</p> | |
569 | ||
570 | <h3> <a name="auto_cpu_timer-synopsis"> <code>auto_cpu_timer</code> synopsis</a></h3> | |
571 | ||
572 | <table border="1" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" width="100%"> | |
573 | <tr> | |
574 | <td bgcolor="#D7EEFF"> | |
575 | ||
576 | <pre> | |
577 | class <a name="auto_cpu_timer">auto_cpu_timer</a> : public <a href="#cpu_timer">cpu_timer</a> | |
578 | { | |
579 | public: | |
580 | explicit <a href="#auto_cpu_timer-1">auto_cpu_timer</a>(short places = default_places); | |
581 | <a href="#auto_cpu_timer-2">auto_cpu_timer</a>(short places, const std::string& format); | |
582 | explicit <a href="#auto_cpu_timer-3">auto_cpu_timer</a>(const std::string& format); | |
583 | <a href="#auto_cpu_timer-4">auto_cpu_timer</a>(std::ostream& os, short places, const std::string& format); | |
584 | explicit <a href="#auto_cpu_timer-5">auto_cpu_timer</a>(std::ostream& os, short places = default_places); | |
585 | <a href="#auto_cpu_timer-6">auto_cpu_timer</a>(std::ostream& os, const std::string& format); | |
586 | ||
587 | <a href="#auto_cpu_timer-destructor">~auto_cpu_timer</a>() noexcept; | |
588 | ||
589 | // compiler generated; shown for exposition only | |
590 | auto_cpu_timer(const auto_cpu_timer&) = default; | |
591 | auto_cpu_timer& operator=(const auto_cpu_timer&) = default; | |
592 | ||
593 | // <a href="#auto_cpu_timer-observers">observers</a> | |
594 | std::ostream& <a href="#ostream">ostream</a>() const noexcept; | |
595 | short <a href="#places">places</a>() const noexcept; | |
596 | const std::string& <a href="#format_string">format_string</a>() const noexcept; | |
597 | ||
598 | // <a href="#auto_cpu_timer-actions">actions</a> | |
599 | void <a href="#report">report</a>(); | |
600 | };</pre> | |
601 | </td> | |
602 | </tr> | |
603 | </table> | |
604 | <p dir="ltr">[<i>Note:</i> Constructors without a <code>std::ostream&</code> | |
605 | argument argument imply <code> | |
606 | std::cout</code>. An argument default is avoided as it would require including <code><iostream></code>, | |
607 | with its high costs, even when the standard streams are not used. <i>--end note</i>]</p> | |
608 | ||
609 | <h3><a name="auto_cpu_timer-constructors"><code>auto_cpu_timer</code> constructors</a></h3> | |
610 | ||
611 | <pre><span style="background-color: #D7EEFF">explicit <a name="auto_cpu_timer-1">auto_cpu_timer</a>(short</span><span style="background-color: #D7EEFF"> places = </span><span style="background-color: #D7EEFF">default_places</span><span style="background-color: #D7EEFF">); | |
612 | <a name="auto_cpu_timer-2">auto_cpu_timer</a>(short</span><span style="background-color: #D7EEFF"> places, const std::string& format); | |
613 | explicit <a name="auto_cpu_timer-3">auto_cpu_timer</a>(const</span><span style="background-color: #D7EEFF"> std::string& format); | |
614 | <a name="auto_cpu_timer-4">auto_cpu_timer</a>(std::ostream</span><span style="background-color: #D7EEFF">& </span><span style="background-color: #D7EEFF">os</span><span style="background-color: #D7EEFF">, short places, const std::string& format);<br>explicit <a name="auto_cpu_timer-5">auto_cpu_timer</a>(std::ostream</span><span style="background-color: #D7EEFF">& </span><span style="background-color: #D7EEFF">os</span><span style="background-color: #D7EEFF">, short places = </span><span style="background-color: #D7EEFF">default_places</span><span style="background-color: #D7EEFF">);<br> <a name="auto_cpu_timer-6">auto_cpu_timer</a>(std::ostream</span><span style="background-color: #D7EEFF">& </span><span style="background-color: #D7EEFF">os</span><span style="background-color: #D7EEFF">, const std::string& format); | |
615 | </span></pre> | |
616 | <blockquote> | |
617 | <p><i>Effects:</i> Constructs an object of type <code> | |
618 | auto_cpu_timer</code> and stores the ostream, places, and format string data | |
619 | needed to establish the postconditions.</p> | |
620 | <p><i>Postconditions:</i></p> | |
621 | <ul> | |
622 | <li>For overloads with an <code>os</code> argument, <code>ostream() == os</code>. | |
623 | Otherwise <code>ostream() == std::cout</code>.</li> | |
624 | <li><code>places() == places</code>.</li> | |
625 | <li>For overloads with a <code>format</code> argument, <code>format_string() | |
626 | == format</code>. Otherwise <code>format_string() == std::cout</code></li> | |
627 | </ul> | |
628 | </blockquote> | |
629 | <h3><a name="auto_cpu_timer-destructor"><code>auto_cpu_timer</code> destructor</a></h3> | |
630 | <pre><span style="background-color: #D7EEFF">~</span><span style="background-color: #D7EEFF">auto_cpu_timer</span><span style="background-color: #D7EEFF">() noexcept;</span></pre> | |
631 | <blockquote> | |
632 | <p dir="ltr"><i>Effects: </i>If <code>!is_stopped()</code>, stop(), <a href="#report"> | |
633 | report()</a>.</p> | |
634 | <p dir="ltr">[<i>Note:</i> Because the function is <code>noexcept</code>, | |
635 | implementation must ensure no exception | |
636 | escapes. <i>--end note</i>]</p> | |
637 | </blockquote> | |
638 | <h3><a name="auto_cpu_timer-observers">auto_cpu_timer observers</a></h3> | |
639 | <p>The observers allow testing of constructor postconditions and specification | |
640 | of other functionality without resorting to "for exposition only" private | |
641 | members.</p> | |
642 | <pre><span style="background-color: #D7EEFF">std::ostream& <a name="ostream">ostream</a>() const noexcept;</span></pre> | |
643 | <blockquote> | |
644 | <p><i>Returns:</i> The ostream stored by construction or subsequent copy | |
645 | assignment.</p> | |
646 | </blockquote> | |
647 | <pre><span style="background-color: #D7EEFF">short <a name="places">places</a>() const noexcept;</span></pre> | |
648 | <blockquote> | |
649 | <p><i>Returns:</i> The places stored by construction or subsequent copy | |
650 | assignment.</p> | |
651 | </blockquote> | |
652 | <pre><span style="background-color: #D7EEFF">const std::string& <a name="format_string">format_string</a>() const noexcept;</span></pre> | |
653 | <blockquote> | |
654 | <p><i>Returns:</i> The format string stored by construction or subsequent copy | |
655 | assignment.</p> | |
656 | </blockquote> | |
657 | <h3><a name="auto_cpu_timer-actions"><code>auto_cpu_timer</code> actions</a></h3> | |
658 | <pre><span style="background-color: #D7EEFF">void <a name="report">report</a>();</span></pre> | |
659 | <blockquote> | |
660 | <p><i>Effects: </i>As if:</p> | |
661 | <blockquote> | |
662 | <pre>ostream() << timer::format(elapsed(), places(), format_string());</pre> | |
663 | </blockquote> | |
664 | ||
665 | <p>[<i>Note: </i>It may be desirable to call <code>stop()</code> before | |
666 | calling <code>report()</code> because doing I/O while the | |
667 | timer is running might produce misleading results. <code>resume()</code> may | |
668 | be called afterwards to continue timing. <i>--end note</i>]</p> | |
669 | ||
670 | </blockquote> | |
671 | ||
672 | <h2><a name="History">History</a></h2> | |
673 | ||
674 | <p>Beman Dawes and Rob Stewart developed version 2 of the library.</p> | |
675 | ||
676 | <p>Beman did the initial development. Rob contributed many corrections, comments, and suggestions. In | |
677 | particular, he suggested the <code>resume()</code> and <code>format()</code> | |
678 | functions, resulting in improved ease-of-use for several use cases.</p> | |
679 | ||
680 | <h2><a name="Acknowledgements">Acknowledgements</a></h2> | |
681 | <p>Comments and suggestions came from Greg Rubino, Dave Abrahams, Vicente | |
682 | Botet, and John Maddock.</p> | |
683 | ||
684 | <hr> | |
685 | <p><font size="2">Revised: | |
686 | <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->08 October 2011<!--webbot bot="Timestamp" endspan i-checksum="32193" --></font></p> | |
687 |