47
#if defined(HAVE_GETTIMEOFDAY) && !defined(HAVE_TIMER)
48
typedef struct timeval mytime;
50
static mytime get_time(void)
57
static double elapsed(mytime t1, mytime t0)
59
return (double)(t1.tv_sec - t0.tv_sec) +
60
(double)(t1.tv_usec - t0.tv_usec) * 1.0E-6;
66
#if !defined(HAVE_TIMER) && (defined(__WIN32__) || defined(_WIN32) || defined(_WINDOWS))
47
#if !defined(HAVE_TIMER) && (defined(__WIN32__) || defined(_WIN32) || defined(_WINDOWS) || defined(__CYGWIN__))
67
48
#include <windows.h>
68
49
typedef LARGE_INTEGER mytime;
70
#if defined(HAVE_GETTIMEOFDAY) && !defined(HAVE_TIMER)
71
typedef struct timeval mytime;
73
static mytime get_time(void)
80
static double elapsed(mytime t1, mytime t0)
82
return (double)(t1.tv_sec - t0.tv_sec) +
83
(double)(t1.tv_usec - t0.tv_usec) * 1.0E-6;
89
90
#error "timer not defined"
93
* Routines to calibrate the slow timer. Derived from Larry McVoy's
94
* lmbench, distributed under the GNU General Public License.
98
From: "Staelin, Carl" <staelin@exch.hpl.hp.com>
99
To: Larry McVoy <lm@bitmover.com>, athena@fftw.org, stevenj@alum.mit.edu
100
Date: Sat, 7 Jul 2001 23:50:49 -0700
104
You have my permission to use the enough_duration,
105
duration, time_N, find_N, test_time, and
106
compute_enough from lib_timing.c routines
107
under the LGPL license. You may also use the
108
BENCH* macros from bench.h under the LGPL
109
if you find them useful.
115
static const double tmin_try = 1.0e-6; /* seconds */
116
93
static const double tmax_try = 1.0; /* seconds */
117
static const double tolerance = 0.001;
119
static TYPE **work(int n, TYPE **p)
121
#define ENOUGH_DURATION_TEN(one) one one one one one one one one one one
123
ENOUGH_DURATION_TEN(p = (TYPE **) *p;);
128
/* do N units of work */
129
static double duration(int n)
131
TYPE *x = (TYPE *)&x;
132
TYPE **p = (TYPE **)&x;
94
static const int nmin = 128, nmax = 133;
96
static double time_one(int n)
102
for (i = 0; i < 16; ++i)
106
for (i = 0; i < n; ++i)
107
bench_fft8(X, X+1, Y, Y+1, 2, 2);
138
109
return (elapsed(t1, t0));
147
118
for (i = 1; i < time_repeat; ++i) {
148
double t = duration(n);
119
double t = time_one(n);
155
/* return the amount of work needed to run TMIN seconds */
156
static int find_n(double tmin)
126
static int good_enough_p(int n, double *tp)
164
for (tries = 0; tries < 10; ++tries) {
165
if (0.98 * tmin < t && t < 1.02 * tmin)
131
/* vary nmin and see if time scales proportionally */
132
for (i = nmin; i < nmax; ++i) {
133
double t1 = time_n(n * i);
136
return 0; /* not enough resolution */
138
if (t1 >= tmax_try) {
181
/* Verify that small modifications affect the runtime proportionally */
182
static int acceptable(double tmin)
186
static const double test_points[] = { 1.015, 1.02, 1.035 };
193
baseline = time_n(n);
195
for (i = 0; i < sizeof(test_points) / sizeof(double); ++i) {
196
double usecs = time_n((int)((double) n * test_points[i]));
197
double expected = baseline * test_points[i];
198
double diff = expected > usecs ? expected - usecs : usecs - expected;
199
if (diff / expected > tolerance)
143
t = (i == nmin) ? t1 : t;
145
if (t1 >= (t * (i + 0.5) / nmin))
148
if (t1 <= (t * (i - 0.5) / nmin))
205
156
static double calibrate(void)
209
for (tmin = tmin_try; tmin < tmax_try && !acceptable(tmin); tmin *= 2.0)
161
for (n = 1; n < (1 << 20); n += n)
162
if (good_enough_p(n, &t))
230
184
time_min = calibrate();
187
static mytime t0[BENCH_NTIMERS];
235
void timer_start(void)
189
void timer_start(int n)
191
BENCH_ASSERT(n >= 0 && n < BENCH_NTIMERS);
240
double timer_stop(void)
195
double timer_stop(int n)
198
BENCH_ASSERT(n >= 0 && n < BENCH_NTIMERS);
244
return elapsed(t1, t0);
200
return elapsed(t1, t0[n]);