annotate fft/fftw/fftw-3.3.4/kernel/timer.c @ 40:223f770b5341 kissfft-double tip

Try a double-precision kissfft
author Chris Cannam
date Wed, 07 Sep 2016 10:40:32 +0100
parents 26056e866c29
children
rev   line source
Chris@19 1 /*
Chris@19 2 * Copyright (c) 2003, 2007-14 Matteo Frigo
Chris@19 3 * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
Chris@19 4 *
Chris@19 5 * This program is free software; you can redistribute it and/or modify
Chris@19 6 * it under the terms of the GNU General Public License as published by
Chris@19 7 * the Free Software Foundation; either version 2 of the License, or
Chris@19 8 * (at your option) any later version.
Chris@19 9 *
Chris@19 10 * This program is distributed in the hope that it will be useful,
Chris@19 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@19 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@19 13 * GNU General Public License for more details.
Chris@19 14 *
Chris@19 15 * You should have received a copy of the GNU General Public License
Chris@19 16 * along with this program; if not, write to the Free Software
Chris@19 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Chris@19 18 *
Chris@19 19 */
Chris@19 20
Chris@19 21
Chris@19 22 #include "ifftw.h"
Chris@19 23
Chris@19 24 #ifdef HAVE_UNISTD_H
Chris@19 25 # include <unistd.h>
Chris@19 26 #endif
Chris@19 27
Chris@19 28 #ifndef WITH_SLOW_TIMER
Chris@19 29 # include "cycle.h"
Chris@19 30 #endif
Chris@19 31
Chris@19 32 #ifndef FFTW_TIME_LIMIT
Chris@19 33 #define FFTW_TIME_LIMIT 2.0 /* don't run for more than two seconds */
Chris@19 34 #endif
Chris@19 35
Chris@19 36 /* the following code is disabled for now, because it seems to
Chris@19 37 require that we #include <windows.h> in ifftw.h to
Chris@19 38 typedef LARGE_INTEGER crude_time, and this pulls in the whole
Chris@19 39 Windows universe and leads to namespace conflicts (unless
Chris@19 40 we did some hack like assuming sizeof(LARGE_INTEGER) == sizeof(long long).
Chris@19 41 gettimeofday is provided by MinGW, which we use to cross-compile
Chris@19 42 FFTW for Windows, and this seems to work well enough */
Chris@19 43 #if 0 && (defined(__WIN32__) || defined(_WIN32) || defined(_WIN64))
Chris@19 44 crude_time X(get_crude_time)(void)
Chris@19 45 {
Chris@19 46 crude_time tv;
Chris@19 47 QueryPerformanceCounter(&tv);
Chris@19 48 return tv;
Chris@19 49 }
Chris@19 50
Chris@19 51 static double elapsed_since(crude_time t0)
Chris@19 52 {
Chris@19 53 crude_time t1, freq;
Chris@19 54 QueryPerformanceCounter(&t1);
Chris@19 55 QueryPerformanceFrequency(&freq);
Chris@19 56 return (((double) (t1.QuadPart - t0.QuadPart))) /
Chris@19 57 ((double) freq.QuadPart);
Chris@19 58 }
Chris@19 59
Chris@19 60 # define TIME_MIN_SEC 1.0e-2
Chris@19 61
Chris@19 62 #elif defined(HAVE_GETTIMEOFDAY)
Chris@19 63 crude_time X(get_crude_time)(void)
Chris@19 64 {
Chris@19 65 crude_time tv;
Chris@19 66 gettimeofday(&tv, 0);
Chris@19 67 return tv;
Chris@19 68 }
Chris@19 69
Chris@19 70 #define elapsed_sec(t1,t0) ((double)(t1.tv_sec - t0.tv_sec) + \
Chris@19 71 (double)(t1.tv_usec - t0.tv_usec) * 1.0E-6)
Chris@19 72
Chris@19 73 static double elapsed_since(crude_time t0)
Chris@19 74 {
Chris@19 75 crude_time t1;
Chris@19 76 gettimeofday(&t1, 0);
Chris@19 77 return elapsed_sec(t1, t0);
Chris@19 78 }
Chris@19 79
Chris@19 80 # define TIME_MIN_SEC 1.0e-3
Chris@19 81
Chris@19 82 #else /* !HAVE_GETTIMEOFDAY */
Chris@19 83
Chris@19 84 /* Note that the only system where we are likely to need to fall back
Chris@19 85 on the clock() function is Windows, for which CLOCKS_PER_SEC is 1000
Chris@19 86 and thus the clock wraps once every 50 days. This should hopefully
Chris@19 87 be longer than the time required to create any single plan! */
Chris@19 88 crude_time X(get_crude_time)(void) { return clock(); }
Chris@19 89
Chris@19 90 #define elapsed_sec(t1,t0) ((double) ((t1) - (t0)) / CLOCKS_PER_SEC)
Chris@19 91
Chris@19 92 static double elapsed_since(crude_time t0)
Chris@19 93 {
Chris@19 94 return elapsed_sec(clock(), t0);
Chris@19 95 }
Chris@19 96
Chris@19 97 # define TIME_MIN_SEC 2.0e-1 /* from fftw2 */
Chris@19 98
Chris@19 99 #endif /* !HAVE_GETTIMEOFDAY */
Chris@19 100
Chris@19 101 double X(elapsed_since)(const planner *plnr, const problem *p, crude_time t0)
Chris@19 102 {
Chris@19 103 double t = elapsed_since(t0);
Chris@19 104 if (plnr->cost_hook)
Chris@19 105 t = plnr->cost_hook(p, t, COST_MAX);
Chris@19 106 return t;
Chris@19 107 }
Chris@19 108
Chris@19 109 #ifdef WITH_SLOW_TIMER
Chris@19 110 /* excruciatingly slow; only use this if there is no choice! */
Chris@19 111 typedef crude_time ticks;
Chris@19 112 # define getticks X(get_crude_time)
Chris@19 113 # define elapsed(t1,t0) elapsed_sec(t1,t0)
Chris@19 114 # define TIME_MIN TIME_MIN_SEC
Chris@19 115 # define TIME_REPEAT 4 /* from fftw2 */
Chris@19 116 # define HAVE_TICK_COUNTER
Chris@19 117 #endif
Chris@19 118
Chris@19 119 #ifdef HAVE_TICK_COUNTER
Chris@19 120
Chris@19 121 # ifndef TIME_MIN
Chris@19 122 # define TIME_MIN 100.0
Chris@19 123 # endif
Chris@19 124
Chris@19 125 # ifndef TIME_REPEAT
Chris@19 126 # define TIME_REPEAT 8
Chris@19 127 # endif
Chris@19 128
Chris@19 129 static double measure(plan *pln, const problem *p, int iter)
Chris@19 130 {
Chris@19 131 ticks t0, t1;
Chris@19 132 int i;
Chris@19 133
Chris@19 134 t0 = getticks();
Chris@19 135 for (i = 0; i < iter; ++i)
Chris@19 136 pln->adt->solve(pln, p);
Chris@19 137 t1 = getticks();
Chris@19 138 return elapsed(t1, t0);
Chris@19 139 }
Chris@19 140
Chris@19 141
Chris@19 142 double X(measure_execution_time)(const planner *plnr,
Chris@19 143 plan *pln, const problem *p)
Chris@19 144 {
Chris@19 145 int iter;
Chris@19 146 int repeat;
Chris@19 147
Chris@19 148 X(plan_awake)(pln, AWAKE_ZERO);
Chris@19 149 p->adt->zero(p);
Chris@19 150
Chris@19 151 start_over:
Chris@19 152 for (iter = 1; iter; iter *= 2) {
Chris@19 153 double tmin = 0;
Chris@19 154 int first = 1;
Chris@19 155 crude_time begin = X(get_crude_time)();
Chris@19 156
Chris@19 157 /* repeat the measurement TIME_REPEAT times */
Chris@19 158 for (repeat = 0; repeat < TIME_REPEAT; ++repeat) {
Chris@19 159 double t = measure(pln, p, iter);
Chris@19 160
Chris@19 161 if (plnr->cost_hook)
Chris@19 162 t = plnr->cost_hook(p, t, COST_MAX);
Chris@19 163 if (t < 0)
Chris@19 164 goto start_over;
Chris@19 165
Chris@19 166 if (first || t < tmin)
Chris@19 167 tmin = t;
Chris@19 168 first = 0;
Chris@19 169
Chris@19 170 /* do not run for too long */
Chris@19 171 if (X(elapsed_since)(plnr, p, begin) > FFTW_TIME_LIMIT)
Chris@19 172 break;
Chris@19 173 }
Chris@19 174
Chris@19 175 if (tmin >= TIME_MIN) {
Chris@19 176 X(plan_awake)(pln, SLEEPY);
Chris@19 177 return tmin / (double) iter;
Chris@19 178 }
Chris@19 179 }
Chris@19 180 goto start_over; /* may happen if timer is screwed up */
Chris@19 181 }
Chris@19 182
Chris@19 183 #else /* no cycle counter */
Chris@19 184
Chris@19 185 double X(measure_execution_time)(const planner *plnr,
Chris@19 186 plan *pln, const problem *p)
Chris@19 187 {
Chris@19 188 UNUSED(plnr);
Chris@19 189 UNUSED(p);
Chris@19 190 UNUSED(pln);
Chris@19 191 return -1.0;
Chris@19 192 }
Chris@19 193
Chris@19 194 #endif