| version 1.6, 2002/07/19 09:29:30 |
version 1.7, 2002/07/31 00:49:36 |
|
|
| #ifndef _PLATON_UTILS_RDTSC_H |
#ifndef _PLATON_UTILS_RDTSC_H |
| #define _PLATON_UTILS_RDTSC_H |
#define _PLATON_UTILS_RDTSC_H |
| |
|
| |
/* |
| |
* $Id$ |
| |
*/ |
| |
|
| |
#define RDTSC_FIRST 0 /* set the first results; default behaviour */ |
| |
#define RDTSC_MIN 1 /* set the shortest result */ |
| |
#define RDTSC_MAX 2 /* set the longest result */ |
| |
#define RDTSC_AVG 3 /* set the average result */ |
| |
|
| #ifdef __cplusplus |
#ifdef __cplusplus |
| extern "C" { |
extern "C" { |
| #endif |
#endif |
| |
|
| #define rdtsc(code, count) { \ |
#define rdtsc_first(code, count, result) \ |
| |
rdtsc_core(RDTSC_FIRST, code, count, result) |
| |
|
| |
#define rdtsc_min(code, count, result) \ |
| |
rdtsc_core(RDTSC_MIN, code, count, result) |
| |
|
| |
#define rdtsc_max(code, count, result) \ |
| |
rdtsc_core(RDTSC_MAX, code, count, result) |
| |
|
| |
#define rdtsc_avg(code, count, result) \ |
| |
rdtsc_core(RDTSC_AVG, code, count, result) |
| |
|
| |
#define rdtsc_core(type, code, count, result) \ |
| |
do { \ |
| unsigned long __start, __end, __i; \ |
unsigned long __start, __end, __i; \ |
| unsigned long __min,__avg = 0,__max,__tmp[(count)]; \ |
double __result; \ |
| for (__i = 0; __i < (count); __i++) { \ |
for (__i = 0; __i < (count); __i++) { \ |
| __asm__ __volatile__("rdtsc" : "=a" (__start) : : "edx"); \ |
__asm__ __volatile__("rdtsc" : "=a" (__start) : : "edx"); \ |
| (code); \ |
(code); \ |
| __asm__ __volatile__("rdtsc" : "=a" (__end) : : "edx"); \ |
__asm__ __volatile__("rdtsc" : "=a" (__end) : : "edx"); \ |
| __tmp[__i] = __end - __start; \ |
__end -= __start; \ |
| __avg += __tmp[__i]; \ |
if ((type) == RDTSC_AVG) { \ |
| }\ |
/* compute average value on the fly */ \ |
| __min = __max = __tmp[0];\ |
/* can't be optimized due overflow */ \ |
| for(__i = 1; __i < (count);__i++) { \ |
__result = (__result * ((double) __i / ((double) __i + 1)) \ |
| if(__tmp[__i] < __min)\ |
+ (double) __end / ((double) __i + 1)); \ |
| __min = __tmp[__i];\ |
} \ |
| if(__tmp[__i] > __max)\ |
else { \ |
| __max = __tmp[__i];\ |
if (! __i \ |
| }\ |
|| ((type) == RDTSC_MIN && __end < __result) \ |
| printf("min: %lu avg: %lu max: %lu count: %d\n",\ |
|| ((type) == RDTSC_MAX && __end > __result)) \ |
| __min,__avg / (count),__max,(count));\ |
__result = __end; \ |
| }\ |
} \ |
| |
} \ |
| |
(result) = __result; \ |
| |
} while(0) |
| |
|
| #ifdef __cplusplus |
#ifdef __cplusplus |
| } |
} |
| #endif |
#endif |
| |
|
| #endif /* #ifndef _PLATON_UTILS_RDTSC_H */ |
#endif /* #ifndef _PLATON_UTILS_RDTSC_H */ |
| |
|