1 #ifndef SKEPU_TIMING_H___
2 #define SKEPU_TIMING_H___
10 #define HAVE_CLOCK_GETTIME
24 skepu_clock_gettime(&start_ts);
28 skepu_clock_gettime(&stop_ts);
29 m_data.push_back(skepu_timing_timespec_delay_us(&start_ts, &stop_ts));
31 double getAverageTime()
36 return (getTotalTime()/m_data.size());
41 for(
int i=0; i<m_data.size(); ++i)
59 void skepu_timing_init(
void);
60 void skepu_clock_gettime(
struct timespec *ts);
62 std::vector<double> m_data;
64 struct timespec start_ts;
65 struct timespec stop_ts;
66 struct timespec skepu_reference_start_time_ts;
69 void skepu_timespec_sub(
const struct timespec *a,
const struct timespec *b,
struct timespec *result)
71 result->tv_sec = a->tv_sec - b->tv_sec;
72 result->tv_nsec = a->tv_nsec - b->tv_nsec;
74 if ((result)->tv_nsec < 0)
77 result->tv_nsec += 1000000000;
83 double skepu_timing_timespec_delay_us(
struct timespec *start,
struct timespec *end)
87 skepu_timespec_sub(end, start, &diff);
89 double us = (diff.tv_sec*1e6) + (diff.tv_nsec*1e-3);
94 double skepu_timing_timespec_to_us(
struct timespec *ts)
96 return (1000000.0*ts->tv_sec) + (0.001*ts->tv_nsec);
99 double skepu_timing_now(
void)
102 skepu_clock_gettime(&now);
104 return skepu_timing_timespec_to_us(&now);
121 #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
124 #ifndef _POSIX_C_SOURCE
126 #define _POSIX_C_SOURCE 199309L
130 #ifndef CLOCK_MONOTONIC_RAW
131 #define CLOCK_MONOTONIC_RAW 4
135 static struct timespec skepu_reference_start_time_ts;
141 static void skepu_clock_readtime(
struct timespec *ts)
143 #ifdef CLOCK_MONOTONIC_RAW
144 static int raw_supported = 0;
145 switch (raw_supported)
150 clock_gettime(CLOCK_MONOTONIC_RAW, ts);
153 if (clock_gettime(CLOCK_MONOTONIC_RAW, ts))
165 clock_gettime(CLOCK_MONOTONIC, ts);
168 void Timer::skepu_timing_init(
void)
170 skepu_clock_gettime(&skepu_reference_start_time_ts);
173 void Timer::skepu_clock_gettime(
struct timespec *ts)
175 struct timespec absolute_ts;
178 skepu_clock_readtime(&absolute_ts);
181 skepu_timespec_sub(&absolute_ts, &skepu_reference_start_time_ts, ts);
184 #else // !HAVE_CLOCK_GETTIME
198 #define SKEPU_MIN(a,b) ((a)<(b)?(a):(b))
200 #define SKEPU_GET_TICK(t) __asm__ volatile("rdtsc" : "=a" ((t).sub.low), "=d" ((t).sub.high))
201 #define SKEPU_TICK_RAW_DIFF(t1, t2) ((t2).tick - (t1).tick)
202 #define SKEPU_TICK_DIFF(t1, t2) (SKEPU_TICK_RAW_DIFF(t1, t2) - skepu_residual)
204 static union skepu_u_tick skepu_reference_start_tick;
205 static double skepu_scale = 0.0;
206 static unsigned long long skepu_residual = 0;
208 static int skepu_inited = 0;
210 void Tuner::skepu_timing_init(
void)
212 static union skepu_u_tick t1, t2;
215 if (skepu_inited)
return;
217 skepu_residual = (
unsigned long long)1 << 63;
219 for(i = 0; i < 20; i++)
223 skepu_residual = SKEPU_MIN(skepu_residual, SKEPU_TICK_RAW_DIFF(t1, t2));
227 struct timeval tv1,tv2;
230 gettimeofday(&tv1,0);
233 gettimeofday(&tv2,0);
234 skepu_scale = ((tv2.tv_sec*1e6 + tv2.tv_usec) -
235 (tv1.tv_sec*1e6 + tv1.tv_usec)) /
236 (
double)(SKEPU_TICK_DIFF(t1, t2));
239 SKEPU_GET_TICK(skepu_reference_start_tick);
244 void Timer::skepu_clock_gettime(
struct timespec *ts)
246 union skepu_u_tick tick_now;
248 SKEPU_GET_TICK(tick_now);
250 uint64_t elapsed_ticks = SKEPU_TICK_DIFF(skepu_reference_start_tick, tick_now);
254 uint64_t elapsed_ns = (uint64_t)(((
double)elapsed_ticks)*(skepu_scale*1000.0));
256 long tv_nsec = (elapsed_ns % 1000000000);
257 time_t tv_sec = (elapsed_ns / 1000000000);
260 ts->tv_nsec = tv_nsec;
264 #endif // HAVE_CLOCK_GETTIME