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#include <casacore/casa/aips.h>
30#include <cstdlib>
31#include <iostream>
32
33#if defined __ia64__ && defined __INTEL_COMPILER
34#include <ia64regs.h>
35#endif
36
37namespace casacore { // # NAMESPACE CASACORE - BEGIN
38
39// Forward Declaration.
40class String;
41
42// <summary>
43// Precision timer to measure elapsed times in a cumulative way
44// </summary>
45
46// <use visibility=export>
47
48// <reviewed reviewer="" date="" tests="tPrecTimer" demos="">
49// </reviewed>
50
51// <synopsis>
52// The PrecTimer supplements the <linkto class=Timer>Timer</linkto> class.
53// If offers a low-overhead and high-resolution interval timer for use
54// on i386, x86_64, ia64, and powerpc platforms, using the processor's
55// timestamp counter that is incremented each cycle.
56// Put timer.start() and timer.stop() calls around the piece of
57// code to be timed. Because the timer is cumulative, the total time of
58// a particular piece of code can be timed.
59// <note role=caution>
60// Make sure that start() and stop() calls alternate,
61// otherwise very strange times will be the result.
62// </note>
63//
64// A timer can be started and stopped multiple times; both the average and
65// total time, as well as the number of iterations are printed.
66// The measured time is real time (as opposed to user or system time).
67// The timer can be used to measure from 10 nanosecond to a century interval.
68//
69// Multiple timers can be used in a nested way as long as each of them
70// has independent (matching) start and stop calls.
71//
72// The class is more or less a copy of the original written by John Romein
73// at ASTRON, Dwingeloo, the Netherlands.
74// </synopsis>
75
76// <example>
77// Here's how to create a timer, start it (the 'mark' member function)
78// and display a breakdown.
79// <srcblock>
80// PrecTimer ttimer; // the timer is reset at construction time
81// PrecTimer ctimer;
82// ttimer.reset(); // if you want to reset the timer (not needed here)
83// ttimer.start(); // start the total timer
84// for (int i=0; i<n; ++i) {
85// ... do something ...
86// ctimer.start(); // start the calc timer
87// ...do some calculation which will be timed...
88// ctimer.stop(); // and stop it
89// }
90// ttimer.stop();
91// ttimer.show (cout, "Total ");
92// ctimer.show (cout, "Calculations");
93// </srcblock>
94// </example>
95
96class PrecTimer {
97 public:
98 // Construct.
99 PrecTimer();
100
101 // Destruct.
102 ~PrecTimer();
103
104 // Restart the timer.
105 void start();
106 // Stop the timer
107 void stop();
108
109 // Reset the timer to zero.
110 void reset();
111
112 // Show real time on cout or a user supplied stream.
113 // <group>
114 void show() const;
115 void show(std::ostream& os) const;
116 // </group>
117
118 // Show real time on cout or a user supplied
119 // stream preceeded by the string parameter.
120 // <group>
121 void show(const String&) const;
122 void show(std::ostream& os, const String& prefix) const;
123 // </group>
124
125 // Get the real time (in seconds).
126 double getReal() const;
127
128 // Get the total number of times start/stop is done.
129 unsigned long long getCount() const;
130
131 private:
132 void print_time(std::ostream&, double time) const;
133
134 struct TimeStruct {
135#if defined __PPC__
137#else
139#endif
140 };
141 union Union1 {
142 long long total_time;
144 };
145
146#if defined __i386__ && defined __INTEL_COMPILER && defined _OPENMP
147 struct CountStruct {
148 int count_low, count_high;
149 };
150 union Union2 {
151 unsigned long long count;
152 CountStruct s2;
153 };
154#else
155 struct Union2 {
156 unsigned long long count;
157 };
158#endif
159
162
163 static double CPU_speed_in_MHz;
164 static double get_CPU_speed_in_MHz();
165};
166
167inline void PrecTimer::reset() {
168 u1.total_time = 0;
169 u2.count = 0;
170}
171
172inline unsigned long long PrecTimer::getCount() const { return u2.count; }
173
175
177
178inline void PrecTimer::start() {
179#if defined __x86_64__ && defined __INTEL_COMPILER && defined _OPENMP
180 asm volatile(
181 "rdtsc\n\t"
182 "shlq $32,%%rdx\n\t"
183 "leaq (%%rax,%%rdx),%%rax\n\t"
184 "lock;subq %%rax,%0"
185 : "+m"(u1.total_time)
186 :
187 : "rax", "rdx");
188#elif defined __i386__ && defined __INTEL_COMPILER && defined _OPENMP
189 asm volatile(
190 "rdtsc\n\t"
191 "lock;subl %%eax,%0\n\t"
192 "lock;sbbl %%edx,%1"
193 : "+m"(u1.s1.total_time_low), "+m"(u1.s1total_time_high)
194 :
195 : "eax", "edx");
196#elif (defined __i386__ || defined __x86_64__) && \
197 (defined __PATHSCALE__ || (defined __APPLE__ && defined __APPLE_CC__ && __APPLE_CC__ == 5531))
198 unsigned eax, edx;
199
200 asm volatile("rdtsc" : "=a"(eax), "=d"(edx));
201
202 u1.total_time -= ((unsigned long long)edx << 32) + eax;
203#elif (defined __i386__ || defined __x86_64__) && (defined __GNUC__ || defined __INTEL_COMPILER)
204 asm volatile(
205 "rdtsc\n\t"
206 "subl %%eax, %0\n\t"
207 "sbbl %%edx, %1"
208 : "+m"(u1.s1.total_time_low), "+m"(u1.s1.total_time_high)
209 :
210 : "eax", "edx");
211#elif defined __ia64__ && defined __INTEL_COMPILER
212 u1.total_time -= __getReg(_IA64_REG_AR_ITC);
213#elif defined __ia64__ && defined __GNUC__
214 long long time;
215 asm volatile("mov %0=ar.itc" : "=r"(time));
216 u1.total_time -= time;
217#elif defined __PPC__ && (defined __GNUC__ || defined __xlC__)
218 int high, low, retry;
219
220 asm("0:\n\t"
221 "mftbu %0\n\t"
222 "mftb %1\n\t"
223 "mftbu %2\n\t"
224 "cmpw %2,%0\n\t"
225 "bne 0b\n\t"
226 "subfc %3,%1,%3\n\t"
227 "subfe %4,%0,%4"
228 : "=r"(high), "=r"(low), "=r"(retry), "=r"(u1.s1.total_time_low), "=r"(u1.s1.total_time_high)
229 : "3"(u1.s1.total_time_low), "4"(u1.s1.total_time_high));
230#endif
231}
232
233inline void PrecTimer::stop() {
234#if defined __x86_64__ && defined __INTEL_COMPILER && defined _OPENMP
235 asm volatile(
236 "rdtsc\n\t"
237 "shlq $32,%%rdx\n\t"
238 "leaq (%%rax,%%rdx),%%rax\n\t"
239 "lock;addq %%rax,%0"
240 : "+m"(u1.total_time)
241 :
242 : "rax", "rdx");
243#elif defined __i386__ && defined __INTEL_COMPILER && defined _OPENMP
244 asm volatile(
245 "rdtsc\n\t"
246 "lock;addl %%eax, %0\n\t"
247 "lock;adcl %%edx, %1"
248 : "+m"(u1.s1.total_time_low), "+m"(u1.s1.total_time_high)
249 :
250 : "eax", "edx");
251#elif (defined __i386__ || defined __x86_64__) && \
252 (defined __PATHSCALE__ || (defined __APPLE__ && defined __APPLE_CC__ && __APPLE_CC__ == 5531))
253 unsigned eax, edx;
254
255 asm volatile("rdtsc\n\t" : "=a"(eax), "=d"(edx));
256 u1.total_time += ((unsigned long long)edx << 32) + eax;
257#elif (defined __i386__ || defined __x86_64__) && (defined __GNUC__ || defined __INTEL_COMPILER)
258 asm volatile(
259 "rdtsc\n\t"
260 "addl %%eax, %0\n\t"
261 "adcl %%edx, %1"
262 : "+m"(u1.s1.total_time_low), "+m"(u1.s1.total_time_high)
263 :
264 : "eax", "edx");
265#elif defined __ia64__ && defined __INTEL_COMPILER
266 u1.total_time += __getReg(_IA64_REG_AR_ITC);
267#elif defined __ia64__ && defined __GNUC__
268 long long time;
269 asm volatile("mov %0=ar.itc" : "=r"(time));
270 u1.total_time += time;
271#elif defined __PPC__ && (defined __GNUC__ || defined __xlC__)
272 int high, low, retry;
273
274 asm("0:\n\t"
275 "mftbu %0\n\t"
276 "mftb %1\n\t"
277 "mftbu %2\n\t"
278 "cmpw %2,%0\n\t"
279 "bne 0b\n\t"
280 "addc %3,%3,%1\n\t"
281 "adde %4,%4,%0"
282 : "=r"(high), "=r"(low), "=r"(retry), "=r"(u1.s1.total_time_low), "=r"(u1.s1.total_time_high)
283 : "3"(u1.s1.total_time_low), "4"(u1.s1.total_time_high));
284#endif
285
286#if defined __x86_64__ && defined __INTEL_COMPILER && defined _OPENMP
287 asm volatile("lock;addq $1,%0" : "+m"(u2.count));
288#elif defined __i386__ && defined __INTEL_COMPILER && defined _OPENMP
289 asm volatile(
290 "lock;addl $1,%0\n\t"
291 "lock;adcl $0,%1"
292 : "+m"(u2.s2.count_low), "+m"(u2.s2.count_high));
293#else
294 ++u2.count;
295#endif
296}
297
298} // namespace casacore
299
300#endif
static double CPU_speed_in_MHz
Definition PrecTimer.h:163
void show(std::ostream &os, const String &prefix) const
void reset()
Reset the timer to zero.
Definition PrecTimer.h:167
void start()
Restart the timer.
Definition PrecTimer.h:178
void show(std::ostream &os) const
~PrecTimer()
Destruct.
Definition PrecTimer.h:176
unsigned long long getCount() const
Get the total number of times start/stop is done.
Definition PrecTimer.h:172
static double get_CPU_speed_in_MHz()
PrecTimer()
Construct.
Definition PrecTimer.h:174
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:233
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:355
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28
TableExprNode time(const TableExprNode &node)
Definition ExprNode.h:1368
unsigned long long count
Definition PrecTimer.h:156