~ubuntu-branches/ubuntu/precise/judy/precise

« back to all changes in this revision

Viewing changes to test/timeit.c

  • Committer: Bazaar Package Importer
  • Author(s): Troy Heber
  • Date: 2005-03-22 06:55:53 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050322065553-syjpkd48r4re18dn
Tags: 1.0.1-5

* Moving LGPL link in copyright back to LGPL-2.1
* Cleanup of debian/rules: removed explicit refs to 32-bit archs, removed
  unnecessary nostrip, using --man dir to install man pages, moving from
  dh_movefiles to dh_install.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// @(#) $Revision: 4.12 $ $Source: /judy/judy/src/apps/benchmark/timeit.c,v $
 
2
//
 
3
// Timer functions.
 
4
//
 
5
// YOU MUST COMPILE THIS WITH ONE OF THESE DEFINED:
 
6
//
 
7
//   JU_HPUX_PA
 
8
//   JU_HPUX_IPF
 
9
//   JU_LINUX_IA32
 
10
//   JU_LINUX_IPF
 
11
//   JU_WIN_IA32
 
12
//
 
13
// If NONE of these are defined, this whole code section is ifdef'd out to
 
14
// avoid compile/link errors due to usage here of objects not defined in
 
15
// timeit.h.  See end of file.
 
16
//
 
17
// TBD:  Improve on this; possibly it's OK now not to ifdef this out, and get
 
18
// default, low-res timing behavior; see timeit.h.
 
19
//
 
20
// Compile with -D_TIMEIT_TEST to include a main program for testing; see
 
21
// main() below.
 
22
 
 
23
#if (JU_HPUX_PA || JU_LINUX_IA32 || JU_LINUX_IPF)
 
24
#define _TIMEIT_HIGHRES
 
25
#endif
 
26
 
 
27
#ifdef _TIMEIT_HIGHRES
 
28
 
 
29
#include <sys/time.h>           // Win32 uses a whole different paradigm.
 
30
#include <unistd.h>             // for getopt(), which Win32 lacks.
 
31
#include <time.h>
 
32
#include "timeit.h"
 
33
 
 
34
double USecPerClock;    // usec per control register count.
 
35
 
 
36
 
 
37
// ****************************************************************************
 
38
// F I N D   C P U   S P E E D
 
39
//
 
40
// Return microseconds per control/timer register count.  Examples:
 
41
//
 
42
// 0.002 for 500 MHz processor
 
43
// 0.001 for 1 GHz processor
 
44
 
 
45
double find_CPU_speed(void)
 
46
{
 
47
        double DeltaUSec;       // Timing result in uSec.
 
48
        TIMER_vars(tm);         // creates __TVBeg_tm, ...
 
49
                                // (used for consistency with __START_HRTm)
 
50
 
 
51
        gettimeofday(&__TVBeg_tm, NULL);        // get low-res time.
 
52
        __START_HRTm(tm);                       // get __start_tm (high-res).
 
53
        sleep(1);                               // time passes; 1 sec suffices.
 
54
        __END_HRTm(tm);                         // get __stop_tm (high-res).
 
55
        gettimeofday(&__TVEnd_tm, NULL);        // get low-res time.
 
56
 
 
57
// gettimeofday() returns usec; compute elapsed time:
 
58
 
 
59
        DeltaUSec = (((double) __TVEnd_tm.tv_sec * ((double) 1E6))
 
60
                    + (double) __TVEnd_tm.tv_usec)
 
61
                  - (((double) __TVBeg_tm.tv_sec * ((double) 1E6))
 
62
                    + (double) __TVBeg_tm.tv_usec);
 
63
 
 
64
// Control register returns ticks, and the ratio can now be computed:
 
65
 
 
66
        return (DeltaUSec / ((double) (__stop_tm - __start_tm)));
 
67
 
 
68
} // find_CPU_speed()
 
69
 
 
70
#else // _TIMEIT_HIGHRES
 
71
void dummy() {}  // avoid "empty source file" warnings when no _TIMEIT_TEST.
 
72
#endif
 
73
 
 
74
 
 
75
// ****************************************************************************
 
76
//
 
77
// Ifdef the test main() separately, including #includes, for platforms that do
 
78
// not define find_CPU_speed() above.
 
79
 
 
80
#ifdef _TIMEIT_TEST
 
81
 
 
82
#include <sys/time.h>           // Win32 uses a whole different paradigm.
 
83
#include <unistd.h>             // for getopt(), which Win32 lacks.
 
84
#include <stdio.h>
 
85
#include <stdlib.h>
 
86
#include <math.h>
 
87
#include <time.h>
 
88
//#include <values.h>             // for MAXDOUBLE
 
89
#define MAXDOUBLE       (10e99)
 
90
#include "timeit.h"
 
91
 
 
92
 
 
93
// ****************************************************************************
 
94
// M A I N
 
95
//
 
96
// Example code for timeit:
 
97
//
 
98
// To compile and test this program on HP-UX, run the next lines as commands.
 
99
//
 
100
//   cc -Wl,-a,archive -DJU_HPUX_PA -D__HPUX__ -D_TIMEIT_TEST -o timeit timeit.c
 
101
//   timeit                     # run test program.
 
102
//   rm -f timeit               # clean up after test.
 
103
 
 
104
int main(int argc, char **argv)
 
105
{
 
106
        int     i = 0;          // loop index.
 
107
        long    i_max = 10;     // number of loops.
 
108
        int     preload = 1;    // loops to throw away (preload cache).
 
109
        double  ztime;          // timer overhead.
 
110
        double  usec[4];        // for early timing tests.
 
111
        double  DeltaUSec;      // timing result in usec.
 
112
        double  prevtime;       // from previous loop.
 
113
        double  mintime;        // minimum event time.
 
114
        struct timeval tmjunk;  // for throw-away syscall.
 
115
        TIMER_vars(tm1);        // overall timer variables.
 
116
        TIMER_vars(tm2);        // misc + loop timer variables.
 
117
 
 
118
 
 
119
// INITIALIZE:
 
120
 
 
121
        STARTTm(tm1);           // whole program timer.
 
122
 
 
123
        i_max += preload;
 
124
 
 
125
// The first arg is the number of iterations (default is i_max):
 
126
 
 
127
        if (argc > 1)
 
128
        {
 
129
            i = atoi(argv[1]) + preload;
 
130
            if (i > 0) i_max = (long)i;
 
131
        }
 
132
 
 
133
// Calculate timer overhead (ztime):
 
134
 
 
135
#ifdef _TIMEIT_HIGHRES
 
136
        (void) puts("Possible slight delay here due to find_CPU_speed()...");
 
137
#else
 
138
        (void) puts("No high-res clock or find_CPU_speed() for this platform.");
 
139
#endif
 
140
 
 
141
        ztime = 0.0;
 
142
 
 
143
        for (i = 0; i < 100; ++i)       // average many runs.
 
144
        {
 
145
            STARTTm(tm2);
 
146
            ENDTm(DeltaUSec, tm2);
 
147
            ztime += DeltaUSec;
 
148
        }
 
149
        ztime = ztime / ((double) i);
 
150
 
 
151
 
 
152
// SIMPLE TESTS OF TIMER OVERHEAD:
 
153
//
 
154
// Make two passes at both the high-res (if any) and slower timers.
 
155
 
 
156
        (void) puts("\nTiming timers themselves: start, end, end");
 
157
 
 
158
#define PRINTPASS(Desc,Pass)                                            \
 
159
        (void) printf("%-8s pass %d:  %f - %f = %f usec\n", Desc, Pass, \
 
160
                      usec[((Pass) * 2) - 1],  usec[((Pass) * 2) - 2],  \
 
161
                      usec[((Pass) * 2) - 1] - usec[((Pass) * 2) - 2])
 
162
 
 
163
#ifdef _TIMEIT_HIGHRES
 
164
        START_HRTm(tm2);
 
165
        END_HRTm(usec[0], tm2); // throw away in case of sleep(1) here.
 
166
 
 
167
        START_HRTm(tm2);
 
168
        END_HRTm(usec[0], tm2);
 
169
        END_HRTm(usec[1], tm2);
 
170
 
 
171
        START_HRTm(tm2);
 
172
        END_HRTm(usec[2], tm2);
 
173
        END_HRTm(usec[3], tm2);
 
174
 
 
175
        PRINTPASS("High-res", 1);
 
176
        PRINTPASS("High-res", 2);
 
177
#endif
 
178
 
 
179
        STARTTm(tm2);
 
180
        ENDTm(usec[0], tm2);    // throw away in case of sleep(1) here.
 
181
 
 
182
        STARTTm(tm2);
 
183
        ENDTm(usec[0], tm2);
 
184
        ENDTm(usec[1], tm2);
 
185
 
 
186
        STARTTm(tm2);
 
187
        ENDTm(usec[2], tm2);
 
188
        ENDTm(usec[3], tm2);
 
189
 
 
190
        PRINTPASS("Non-HR", 1);
 
191
        PRINTPASS("Non-HR", 2);
 
192
 
 
193
 
 
194
// PRINT INITIAL INFO:
 
195
 
 
196
#ifdef _TIMEIT_HIGHRES
 
197
 
 
198
// Print the CPU speed:
 
199
//
 
200
// Note:  USecPerClock is a global set by the first instance of STARTTm.  You
 
201
// can also get this number by calling find_CPU_speed().
 
202
 
 
203
        (void) printf("\nClock step = %.3f nsec => %.1f MHz.\n",
 
204
                      USecPerClock * 1000.0, 1.0 / USecPerClock);
 
205
#endif
 
206
 
 
207
// Print timer overhead even though it's been subtracted from the reported
 
208
// results.
 
209
 
 
210
        (void) printf("Timer overhead subtracted from the times below = %f "
 
211
                      "usec.\n", ztime);
 
212
 
 
213
 
 
214
// DO A FAST TIMER CHECK:
 
215
 
 
216
        (void) puts("\nCheck timer precision by repeating the same action:");
 
217
        (void) puts("Times in each group should be close together.");
 
218
        (void) puts("\nTiming something very fast: \"++i\":");
 
219
 
 
220
        mintime = MAXDOUBLE;
 
221
 
 
222
        for (i = 1; i <= i_max; ++i)
 
223
        {
 
224
            prevtime = DeltaUSec;
 
225
            STARTTm(tm2);               // start the timer.
 
226
            ++i;                        // statement to time.
 
227
            ENDTm(DeltaUSec, tm2);      // stop the timer.
 
228
            DeltaUSec -= ztime;         // remove timer overhead.
 
229
 
 
230
// Throw away the first loop iteration to warm up the cache:
 
231
 
 
232
            if (--i > preload)
 
233
            {
 
234
                if (mintime == MAXDOUBLE) mintime = DeltaUSec;
 
235
 
 
236
                (void) printf("%3d. %8.3f nanosec,\tmintime diff %8.1f %%\n",
 
237
                              i - preload, DeltaUSec * 1000.0,
 
238
                              ((DeltaUSec - mintime) * 100) / mintime);
 
239
 
 
240
                if (DeltaUSec < mintime) mintime = DeltaUSec;
 
241
            }
 
242
        }
 
243
 
 
244
 
 
245
// TIME A FUNCTION CALL:
 
246
 
 
247
        (void) puts("\nTiming a function: \"gettimeofday()\":");
 
248
        mintime = MAXDOUBLE;
 
249
 
 
250
        for (i = 1; i <= i_max; ++i)
 
251
        {
 
252
            prevtime = DeltaUSec;
 
253
            STARTTm(tm2);                       // start the timer.
 
254
            gettimeofday(&tmjunk, NULL);        // burn some cycles.
 
255
            ENDTm(DeltaUSec, tm2);              // stop the timer.
 
256
            DeltaUSec -= ztime;                 // remove timer overhead.
 
257
 
 
258
// Throw away the first loop iteration to warm up the cache:
 
259
 
 
260
            if (i > preload)
 
261
            {
 
262
                if (mintime == MAXDOUBLE) mintime = DeltaUSec;
 
263
 
 
264
                (void) printf("%3d. %8.3f usec,\tmintime diff %8.1f %%\n",
 
265
                              i - preload, DeltaUSec,
 
266
                              ((DeltaUSec - mintime) * 100) / mintime);
 
267
 
 
268
                if (DeltaUSec < mintime) mintime = DeltaUSec;
 
269
            }
 
270
        }
 
271
 
 
272
 
 
273
// TIME SOMETHING SLOW:
 
274
 
 
275
        (void) puts("\nTiming something slow: \"sleep(1)\":");
 
276
        mintime = MAXDOUBLE;
 
277
 
 
278
        for (i = 1; i <= i_max; ++i)
 
279
        {
 
280
            prevtime = DeltaUSec;
 
281
            STARTTm(tm2);               // start the timer.
 
282
            sleep(1);
 
283
            ENDTm(DeltaUSec, tm2);      // stop the timer.
 
284
            DeltaUSec -= ztime;         // remove timer overhead.
 
285
 
 
286
// Throw away the first loop iteration to warm up the cache:
 
287
 
 
288
            if (i > preload)
 
289
            {
 
290
                if (mintime == MAXDOUBLE) mintime = DeltaUSec;
 
291
 
 
292
                (void) printf("%3d. %8.3f sec,\tmintime diff %8.1f %%\n",
 
293
                              i - preload, DeltaUSec/1E6,
 
294
                              ((DeltaUSec - mintime) * 100) / mintime);
 
295
 
 
296
                if (DeltaUSec < mintime) mintime = DeltaUSec;
 
297
            }
 
298
        }
 
299
 
 
300
 
 
301
// FINISH UP:
 
302
//
 
303
// Print program execution time:
 
304
 
 
305
        ENDTm(DeltaUSec, tm1);
 
306
        (void) printf("\nProgram execution time: %.3f sec\n", DeltaUSec / 1E6);
 
307
        return(0);
 
308
 
 
309
} // main()
 
310
 
 
311
#endif // #ifdef _TIMEIT_TEST