update to set up make variables for compiling modules with libhrtime
[dyninst.git] / common / src / timing.C
1 /*
2  * Copyright (c) 1996 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // $Id: timing.C,v 1.16 2000/10/17 17:42:08 schendel Exp $
43
44 #include <iostream.h>
45 #include "common/h/Timer.h"
46 #include "common/h/timing.h"
47 #include "common/h/Time.h"
48
49
50 #if defined(rs6000_ibm_aix4_1)
51 #define NOPS_4  asm("oril 0,0,0"); asm("oril 0,0,0"); asm("oril 0,0,0"); asm("oril 0,0,0")
52 #elif defined(i386_unknown_nt4_0)
53 #define NOPS_4 { __asm nop __asm nop __asm nop __asm nop }
54 #elif defined(mips_sgi_irix6_4)
55 #  ifndef USES_NATIVE_CC
56 #define NOPS_4  __asm__("nop"); __asm__("nop"); __asm__("nop"); __asm__("nop")
57 #  else
58 #define NOPS_4  ; ; ; 
59 #  endif
60 #else
61 #define NOPS_4  asm("nop"); asm("nop"); asm("nop"); asm("nop")
62 #endif
63
64 #define NOPS_16 NOPS_4; NOPS_4; NOPS_4; NOPS_4
65
66 double timing_loop(const unsigned TRIES, const unsigned LOOP_LIMIT) {
67   const double MILLION = 1.0e6;
68   unsigned       i, j;
69   timer stopwatch;
70   double speed=0, max_speed=0;
71
72   for (j=0; j<TRIES; j++) {
73     stopwatch.start();
74     for (i = 0; i < LOOP_LIMIT; i++) {
75       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
76       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
77       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
78       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
79     }
80     stopwatch.stop();
81     if (stopwatch.usecs() > 0)
82         speed   = ((double)(256*LOOP_LIMIT)/stopwatch.usecs())/MILLION;
83     stopwatch.clear();
84     if (speed > max_speed)
85       max_speed = speed;
86   }
87
88   for (j=0; j<TRIES; j++) {
89     stopwatch.start();
90     for (i = 0; i < LOOP_LIMIT; i++) {
91       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
92       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
93       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
94       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
95       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
96       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
97       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
98       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
99     }
100     stopwatch.stop();
101     if (stopwatch.usecs() > 0)
102         speed   = ((double)(512*LOOP_LIMIT)/stopwatch.usecs())/MILLION;
103     stopwatch.clear();
104     if (speed > max_speed)
105       max_speed = speed;
106   }
107
108   for (j=0; j<TRIES; j++) {
109     stopwatch.start();
110     for (i = 0; i < LOOP_LIMIT; i++) {
111       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
112       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
113       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
114       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
115       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
116       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
117       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
118       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
119       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
120       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
121       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
122       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
123       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
124       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
125       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
126       NOPS_16; NOPS_16; NOPS_16; NOPS_16;
127     }
128     stopwatch.stop();
129     if (stopwatch.usecs() > 0)
130         speed   = ((double)(1024*LOOP_LIMIT)/stopwatch.usecs())/MILLION;
131     stopwatch.clear();
132     if (speed > max_speed)
133       max_speed = speed;
134   }
135
136 #if defined(i386_unknown_solaris2_5) \
137  || defined(i386_unknown_nt4_0) \
138  || defined(i386_unknown_linux2_0)
139   // the speed of the pentium is being overestimated by a factor of 2
140   max_speed /= 2;
141 #elif defined(mips_sgi_irix6_4)
142   max_speed /= 4;
143 #endif
144
145   return max_speed;
146 }
147
148 double calcCyclesPerSecond_default()
149 {
150   double raw = timing_loop(1, 100000) * 1000000.0;
151   return raw;
152 }
153
154 /* time retrieval function definitions */
155
156 timeStamp getCurrentTime() {
157   return timeStamp(getRawTime1970(), timeUnit::us(), timeBase::b1970());
158 }
159
160 #ifndef i386_unknown_nt4_0
161 // returns us since 1970
162 rawTime64 getRawTime1970() {
163   struct timeval tv;
164   if (-1 == gettimeofday(&tv, NULL)) {
165     perror("getCurrentTime gettimeofday()");
166     return 0;
167   }
168   rawTime64 result = tv.tv_sec;
169   result *= 1000000;
170   result += tv.tv_usec;
171   return result;
172 }
173 #endif
174
175
176 // Shows the time until the auxillary fraction conversion algorithm
177 // will be used in order to get around internal rollover 
178 // (see util/src/Time.C).  Auxiliary algorithm requires an additional
179 // 64bit integer div, mult, modulas, addition.  Conversion efficiency
180 // to this degree most likely isn't relevant.
181 //
182 //         Timing statistics for a 1999 MHz machine
183 // fract numer    MHz precision     time until aux alg   time err/year
184 //    1000        1 MHz             7.6 weeks            2.2 hrs
185 //   10000        100,000 Hz        5.3 days             13 minutes
186 //  100000         10,000 Hz        12 hrs               1.3 minutes   *
187 // 1000000          1,000 Hz        1.2 hrs              8 seconds
188 //
189 //         Timing statistics for a  199 MHz machine
190 // fract numer    MHz precision     time until aux alg   time err/year
191 //    1000        1 MHz             7.6 weeks            22 hrs
192 //   10000        100,000 Hz        5.3 days             2.2 hrs
193 //  100000         10,000 Hz        12 hrs               13 minutes    *
194 // 1000000          1,000 Hz        1.2 hrs              1.3 minutes
195 //
196 // * currently using
197 // 10,000 Hz precision, 12 hrs time until aux alg, seems like a good compromise
198
199 // access only through getCyclesPerSecond()
200 timeUnit *pCyclesPerSecond = NULL;
201
202 void initCyclesPerSecond() {
203   double cpsHz = calcCyclesPerSecondOS();
204   double cpsTTHz = cpsHz / 10000.0;
205   // round it
206   cpsTTHz = cpsTTHz + .5;
207   int64_t tenThousHz = static_cast<int64_t>(cpsTTHz);
208   // in case of multiple calls
209   if(pCyclesPerSecond != NULL) delete pCyclesPerSecond;
210   pCyclesPerSecond = new timeUnit(fraction(100000, tenThousHz));
211 }
212
213 timeUnit getCyclesPerSecond() {
214   if(pCyclesPerSecond == NULL) { 
215     cerr << "getCyclesPerSecond(): cycles per second hasn't been initialized\n";
216     assert(0);
217   }
218   return (*pCyclesPerSecond);
219 }