casacore
Loading...
Searching...
No Matches
PrecTimer.h
Go to the documentation of this file.
1//# PrecTimer.h: Precision timer to measure elapsed times in a cumulative way
2//# Copyright (C) 2006
3//# Associated Universities, Inc. Washington DC, USA.
4//#
5//# This library is free software; you can redistribute it and/or modify it
6//# under the terms of the GNU Library General Public License as published by
7//# the Free Software Foundation; either version 2 of the License, or (at your
8//# option) any later version.
9//#
10//# This library is distributed in the hope that it will be useful, but WITHOUT
11//# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12//# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13//# License for more details.
14//#
15//# You should have received a copy of the GNU Library General Public License
16//# along with this library; if not, write to the Free Software Foundation,
17//# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18//#
19//# Correspondence concerning AIPS++ should be addressed as follows:
20//# Internet email: casa-feedback@nrao.edu.
21//# Postal address: AIPS++ Project Office
22//# National Radio Astronomy Observatory
23//# 520 Edgemont Road
24//# Charlottesville, VA 22903-2475 USA
25
26#ifndef CASA_PRECTIMER_H
27#define CASA_PRECTIMER_H
28
29
30#include <casacore/casa/aips.h>
31#include <cstdlib>
32#include <iostream>
33
34#if defined __ia64__ && defined __INTEL_COMPILER
35#include <ia64regs.h>
36#endif
37
38
39namespace casacore { //# NAMESPACE CASACORE - BEGIN
40
41// Forward Declaration.
42class String;
43
44
45// <summary>
46// Precision timer to measure elapsed times in a cumulative way
47// </summary>
48
49// <use visibility=export>
50
51// <reviewed reviewer="" date="" tests="tPrecTimer" demos="">
52// </reviewed>
53
54// <synopsis>
55// The PrecTimer supplements the <linkto class=Timer>Timer</linkto> class.
56// If offers a low-overhead and high-resolution interval timer for use
57// on i386, x86_64, ia64, and powerpc platforms, using the processor's
58// timestamp counter that is incremented each cycle.
59// Put timer.start() and timer.stop() calls around the piece of
60// code to be timed. Because the timer is cumulative, the total time of
61// a particular piece of code can be timed.
62// <note role=caution>
63// Make sure that start() and stop() calls alternate,
64// otherwise very strange times will be the result.
65// </note>
66//
67// A timer can be started and stopped multiple times; both the average and
68// total time, as well as the number of iterations are printed.
69// The measured time is real time (as opposed to user or system time).
70// The timer can be used to measure from 10 nanosecond to a century interval.
71//
72// Multiple timers can be used in a nested way as long as each of them
73// has independent (matching) start and stop calls.
74//
75// The class is more or less a copy of the original written by John Romein
76// at ASTRON, Dwingeloo, the Netherlands.
77// </synopsis>
78
79// <example>
80// Here's how to create a timer, start it (the 'mark' member function)
81// and display a breakdown.
82// <srcblock>
83// PrecTimer ttimer; // the timer is reset at construction time
84// PrecTimer ctimer;
85// ttimer.reset(); // if you want to reset the timer (not needed here)
86// ttimer.start(); // start the total timer
87// for (int i=0; i<n; ++i) {
88// ... do something ...
89// ctimer.start(); // start the calc timer
90// ...do some calculation which will be timed...
91// ctimer.stop(); // and stop it
92// }
93// ttimer.stop();
94// ttimer.show (cout, "Total ");
95// ctimer.show (cout, "Calculations");
96// </srcblock>
97// </example>
98
99 class PrecTimer {
100 public:
101 // Construct.
102 PrecTimer();
103
104 // Destruct.
105 ~PrecTimer();
106
107 // Restart the timer.
108 void start();
109 // Stop the timer
110 void stop();
111
112 // Reset the timer to zero.
113 void reset();
114
115 // Show real time on cout or a user supplied stream.
116 // <group>
117 void show() const;
118 void show (std::ostream& os) const;
119 // </group>
120
121 // Show real time on cout or a user supplied
122 // stream preceeded by the string parameter.
123 // <group>
124 void show (const String&) const;
125 void show (std::ostream& os, const String& prefix) const;
126 // </group>
127
128 // Get the real time (in seconds).
129 double getReal() const;
130
131 // Get the total number of times start/stop is done.
132 unsigned long long getCount() const;
133
134 private:
135 void print_time (std::ostream&, double time) const;
136
137 struct TimeStruct {
138#if defined __PPC__
140#else
142#endif
143 };
144 union Union1 {
145 long long total_time;
147 };
148
149#if defined __i386__ && defined __INTEL_COMPILER && defined _OPENMP
150 struct CountStruct {
151 int count_low, count_high;
152 };
153 union Union2 {
154 unsigned long long count;
155 CountStruct s2;
156 };
157#else
158 struct Union2 {
159 unsigned long long count;
160 };
161#endif
162
165
166 static double CPU_speed_in_MHz;
167 static double get_CPU_speed_in_MHz();
168 };
169
170
171
172 inline void PrecTimer::reset()
173 {
174 u1.total_time = 0;
175 u2.count = 0;
176 }
177
178 inline unsigned long long PrecTimer::getCount() const
179 {
180 return u2.count;
181 }
182
184 {
185 reset();
186 }
187
189 {}
190
191
192 inline void PrecTimer::start()
193 {
194#if defined __x86_64__ && defined __INTEL_COMPILER && defined _OPENMP
195 asm volatile
196 (
197 "rdtsc\n\t"
198 "shlq $32,%%rdx\n\t"
199 "leaq (%%rax,%%rdx),%%rax\n\t"
200 "lock;subq %%rax,%0"
201 :
202 "+m" (u1.total_time)
203 :
204 :
205 "rax", "rdx"
206 );
207#elif defined __i386__ && defined __INTEL_COMPILER && defined _OPENMP
208 asm volatile
209 (
210 "rdtsc\n\t"
211 "lock;subl %%eax,%0\n\t"
212 "lock;sbbl %%edx,%1"
213 :
214 "+m" (u1.s1.total_time_low), "+m" (u1.s1total_time_high)
215 :
216 :
217 "eax", "edx"
218 );
219#elif (defined __i386__ || defined __x86_64__) && (defined __PATHSCALE__ || (defined __APPLE__ && defined __APPLE_CC__ && __APPLE_CC__ == 5531))
220 unsigned eax, edx;
221
222 asm volatile ("rdtsc" : "=a" (eax), "=d" (edx));
223
224 u1.total_time -= ((unsigned long long) edx << 32) + eax;
225#elif (defined __i386__ || defined __x86_64__) && (defined __GNUC__ || defined __INTEL_COMPILER)
226 asm volatile
227 (
228 "rdtsc\n\t"
229 "subl %%eax, %0\n\t"
230 "sbbl %%edx, %1"
231 :
232 "+m" (u1.s1.total_time_low), "+m" (u1.s1.total_time_high)
233 :
234 :
235 "eax", "edx"
236 );
237#elif defined __ia64__ && defined __INTEL_COMPILER
238 u1.total_time -= __getReg(_IA64_REG_AR_ITC);
239#elif defined __ia64__ && defined __GNUC__
240 long long time;
241 asm volatile ("mov %0=ar.itc" : "=r" (time));
242 u1.total_time -= time;
243#elif defined __PPC__ && (defined __GNUC__ || defined __xlC__)
244 int high, low, retry;
245
246 asm
247 (
248 "0:\n\t"
249 "mftbu %0\n\t"
250 "mftb %1\n\t"
251 "mftbu %2\n\t"
252 "cmpw %2,%0\n\t"
253 "bne 0b\n\t"
254 "subfc %3,%1,%3\n\t"
255 "subfe %4,%0,%4"
256 :
257 "=r" (high), "=r" (low), "=r" (retry),
258 "=r" (u1.s1.total_time_low), "=r" (u1.s1.total_time_high)
259 :
261 );
262#endif
263 }
264
265
266 inline void PrecTimer::stop()
267 {
268#if defined __x86_64__ && defined __INTEL_COMPILER && defined _OPENMP
269 asm volatile
270 (
271 "rdtsc\n\t"
272 "shlq $32,%%rdx\n\t"
273 "leaq (%%rax,%%rdx),%%rax\n\t"
274 "lock;addq %%rax,%0"
275 :
276 "+m" (u1.total_time)
277 :
278 :
279 "rax", "rdx"
280 );
281#elif defined __i386__ && defined __INTEL_COMPILER && defined _OPENMP
282 asm volatile
283 (
284 "rdtsc\n\t"
285 "lock;addl %%eax, %0\n\t"
286 "lock;adcl %%edx, %1"
287 :
288 "+m" (u1.s1.total_time_low), "+m" (u1.s1.total_time_high)
289 :
290 :
291 "eax", "edx"
292 );
293#elif (defined __i386__ || defined __x86_64__) && (defined __PATHSCALE__ || (defined __APPLE__ && defined __APPLE_CC__ && __APPLE_CC__ == 5531))
294 unsigned eax, edx;
295
296 asm volatile ("rdtsc\n\t" : "=a" (eax), "=d" (edx));
297 u1.total_time += ((unsigned long long) edx << 32) + eax;
298#elif (defined __i386__ || defined __x86_64__) && (defined __GNUC__ || defined __INTEL_COMPILER)
299 asm volatile
300 (
301 "rdtsc\n\t"
302 "addl %%eax, %0\n\t"
303 "adcl %%edx, %1"
304 :
305 "+m" (u1.s1.total_time_low), "+m" (u1.s1.total_time_high)
306 :
307 :
308 "eax", "edx"
309 );
310#elif defined __ia64__ && defined __INTEL_COMPILER
311 u1.total_time += __getReg(_IA64_REG_AR_ITC);
312#elif defined __ia64__ && defined __GNUC__
313 long long time;
314 asm volatile ("mov %0=ar.itc" : "=r" (time));
315 u1.total_time += time;
316#elif defined __PPC__ && (defined __GNUC__ || defined __xlC__)
317 int high, low, retry;
318
319 asm
320 (
321 "0:\n\t"
322 "mftbu %0\n\t"
323 "mftb %1\n\t"
324 "mftbu %2\n\t"
325 "cmpw %2,%0\n\t"
326 "bne 0b\n\t"
327 "addc %3,%3,%1\n\t"
328 "adde %4,%4,%0"
329 :
330 "=r" (high), "=r" (low), "=r" (retry),
331 "=r" (u1.s1.total_time_low), "=r" (u1.s1.total_time_high)
332 :
334 );
335#endif
336
337#if defined __x86_64__ && defined __INTEL_COMPILER && defined _OPENMP
338 asm volatile ("lock;addq $1,%0" : "+m" (u2.count));
339#elif defined __i386__ && defined __INTEL_COMPILER && defined _OPENMP
340 asm volatile
341 (
342 "lock;addl $1,%0\n\t"
343 "lock;adcl $0,%1"
344 :
345 "+m" (u2.s2.count_low), "+m" (u2.s2.count_high)
346 );
347#else
348 ++u2.count;
349#endif
350 }
351
352} //# NAMESPACE CASACORE - END
353
354
355#endif
static double CPU_speed_in_MHz
Definition PrecTimer.h:166
void show(std::ostream &os, const String &prefix) const
void reset()
Reset the timer to zero.
Definition PrecTimer.h:172
void start()
Restart the timer.
Definition PrecTimer.h:192
void show(std::ostream &os) const
~PrecTimer()
Destruct.
Definition PrecTimer.h:188
unsigned long long getCount() const
Get the total number of times start/stop is done.
Definition PrecTimer.h:178
static double get_CPU_speed_in_MHz()
PrecTimer()
Construct.
Definition PrecTimer.h:183
void show(const String &) const
Show real time on cout or a user supplied stream preceeded by the string parameter.
void print_time(std::ostream &, double time) const
double getReal() const
Get the real time (in seconds).
void stop()
Stop the timer.
Definition PrecTimer.h:266
void show() const
Show real time on cout or a user supplied stream.
String: the storage and methods of handling collections of characters.
Definition String.h:223
this file contains all the compiler specific defines
Definition mainpage.dox:28
TableExprNode time(const TableExprNode &node)
Definition ExprNode.h:1584
unsigned long long count
Definition PrecTimer.h:159