54 #include "my_global.h"
65 #if TIME_WITH_SYS_TIME
71 #elif defined(HAVE_TIME_H)
77 #if defined(HAVE_ASM_MSR_H) && defined(HAVE_RDTSCLL)
81 #if defined(HAVE_SYS_TIMEB_H) && defined(HAVE_FTIME)
82 #include <sys/timeb.h>
85 #if defined(HAVE_SYS_TIMES_H) && defined(HAVE_TIMES)
86 #include <sys/times.h>
89 #if defined(__INTEL_COMPILER) && defined(__ia64__) && defined(HAVE_IA64INTRIN_H)
90 #include <ia64intrin.h>
93 #if defined(__APPLE__) && defined(__MACH__)
94 #include <mach/mach_time.h>
97 #if defined(__SUNPRO_CC) && defined(__sparcv9) && defined(_LP64) && !defined(__SunOS_5_7)
98 extern "C" ulonglong my_timer_cycles_il_sparc64();
99 #elif defined(__SUNPRO_CC) && defined(_ILP32) && !defined(__SunOS_5_7)
100 extern "C" ulonglong my_timer_cycles_il_sparc32();
101 #elif defined(__SUNPRO_CC) && defined(__i386) && defined(_ILP32)
102 extern "C" ulonglong my_timer_cycles_il_i386();
103 #elif defined(__SUNPRO_CC) && defined(__x86_64) && defined(_LP64)
104 extern "C" ulonglong my_timer_cycles_il_x86_64();
105 #elif defined(__SUNPRO_C) && defined(__sparcv9) && defined(_LP64) && !defined(__SunOS_5_7)
106 ulonglong my_timer_cycles_il_sparc64();
107 #elif defined(__SUNPRO_C) && defined(_ILP32) && !defined(__SunOS_5_7)
108 ulonglong my_timer_cycles_il_sparc32();
109 #elif defined(__SUNPRO_C) && defined(__i386) && defined(_ILP32)
110 ulonglong my_timer_cycles_il_i386();
111 #elif defined(__SUNPRO_C) && defined(__x86_64) && defined(_LP64)
112 ulonglong my_timer_cycles_il_x86_64();
115 #if defined(__INTEL_COMPILER)
120 #pragma warning (disable:1011)
134 ulonglong my_timer_cycles(
void)
136 #if defined(__GNUC__) && defined(__i386__)
139 __asm__ __volatile__ (
"rdtsc" :
"=A" (result));
141 #elif defined(__SUNPRO_C) && defined(__i386)
143 #elif defined(__GNUC__) && defined(__x86_64__)
145 __asm__ __volatile__ (
"rdtsc\n\t" \
146 "shlq $32,%%rdx\n\t" \
148 :
"=a" (result) ::
"%edx");
150 #elif defined(HAVE_ASM_MSR_H) && defined(HAVE_RDTSCLL)
156 #elif defined(_WIN32) && defined(_M_IX86)
158 #elif defined(_WIN64) && defined(_M_X64)
161 #elif defined(__INTEL_COMPILER) && defined(__ia64__) && defined(HAVE_IA64INTRIN_H)
162 return (ulonglong) __getReg(_IA64_REG_AR_ITC);
163 #elif defined(__GNUC__) && defined(__ia64__)
166 __asm __volatile__ (
"mov %0=ar.itc" :
"=r" (result));
169 #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__POWERPC__) || (defined(_POWER) && defined(_AIX52))) && (defined(__64BIT__) || defined(_ARCH_PPC64))
172 __asm __volatile__ (
"mftb %0" :
"=r" (result));
175 #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__POWERPC__) || (defined(_POWER) && defined(_AIX52))) && (!defined(__64BIT__) && !defined(_ARCH_PPC64))
182 unsigned int x1, x2, x3;
186 __asm __volatile__ (
"mftbu %0" :
"=r"(x1) );
187 __asm __volatile__ (
"mftb %0" :
"=r"(x2) );
188 __asm __volatile__ (
"mftbu %0" :
"=r"(x3) );
192 return ( result << 32 ) | x2;
194 #elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(__sparcv9) && defined(_LP64) && !defined(__SunOS_5_7)
195 return (my_timer_cycles_il_sparc64());
196 #elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(_ILP32) && !defined(__SunOS_5_7)
197 return (my_timer_cycles_il_sparc32());
198 #elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(__i386) && defined(_ILP32)
200 return (my_timer_cycles_il_i386());
201 #elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(__x86_64) && defined(_LP64)
202 return (my_timer_cycles_il_x86_64());
203 #elif defined(__GNUC__) && defined(__sparcv9) && defined(_LP64) && (__GNUC__>2)
206 __asm __volatile__ (
"rd %%tick,%0" :
"=r" (result));
209 #elif defined(__GNUC__) && defined(__sparc__) && !defined(_LP64) && (__GNUC__>2)
212 ulonglong wholeresult;
218 __asm __volatile__ (
"rd %%tick,%1; srlx %1,32,%0" :
"=r" (result.splitresult.high),
"=r" (result.splitresult.low));
219 return result.wholeresult;
221 #elif defined(__sgi) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_SGI_CYCLE)
224 clock_gettime(CLOCK_SGI_CYCLE, &tp);
225 return (ulonglong) tp.tv_sec * 1000000000 + (ulonglong) tp.tv_nsec;
227 #elif defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME)
229 return (ulonglong) gethrtime();
235 #if defined(__INTEL_COMPILER)
238 #pragma warning (default:1011)
247 ulonglong my_timer_nanoseconds(
void)
249 #if defined(HAVE_READ_REAL_TIME)
252 read_real_time(&tr, TIMEBASE_SZ);
253 return (ulonglong) tr.tb_high * 1000000000 + (ulonglong) tr.tb_low;
255 #elif defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME)
257 return (ulonglong) gethrtime();
258 #elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)
261 clock_gettime(CLOCK_REALTIME, &tp);
262 return (ulonglong) tp.tv_sec * 1000000000 + (ulonglong) tp.tv_nsec;
264 #elif defined(__APPLE__) && defined(__MACH__)
267 static mach_timebase_info_data_t timebase_info= {0,0};
268 if (timebase_info.denom == 0)
269 (void) mach_timebase_info(&timebase_info);
270 tm= mach_absolute_time();
271 return (tm * timebase_info.numer) / timebase_info.denom;
287 ulonglong my_timer_microseconds(
void)
289 #if defined(HAVE_GETTIMEOFDAY)
291 static ulonglong last_value= 0;
293 if (gettimeofday(&tv, NULL) == 0)
294 last_value= (ulonglong) tv.tv_sec * 1000000 + (ulonglong) tv.tv_usec;
307 #elif defined(_WIN32)
312 QueryPerformanceCounter(&t_cnt);
313 return (ulonglong) t_cnt.QuadPart;
327 ulonglong my_timer_milliseconds(
void)
329 #if defined(HAVE_SYS_TIMEB_H) && defined(HAVE_FTIME)
333 return (ulonglong)ft.time * 1000 + (ulonglong)ft.millitm;
334 #elif defined(HAVE_TIME)
335 return (ulonglong) time(NULL) * 1000;
336 #elif defined(_WIN32)
338 GetSystemTimeAsFileTime( &ft );
339 return ((ulonglong)ft.dwLowDateTime +
340 (((ulonglong)ft.dwHighDateTime) << 32))/10000;
352 ulonglong my_timer_ticks(
void)
354 #if defined(HAVE_SYS_TIMES_H) && defined(HAVE_TIMES)
356 struct tms times_buf;
357 return (ulonglong) times(×_buf);
359 #elif defined(_WIN32)
360 return (ulonglong) GetTickCount();
375 #define MY_TIMER_ITERATIONS 1000000
387 static void my_timer_init_overhead(ulonglong *overhead,
388 ulonglong (*cycle_timer)(
void),
389 ulonglong (*this_timer)(
void),
390 ulonglong best_timer_overhead)
392 ulonglong time1, time2;
396 for (i= 0, *overhead= 1000000000; i < 20; ++
i)
398 time1= cycle_timer();
400 time2= cycle_timer() - time1;
401 if (*overhead > time2)
404 *overhead-= best_timer_overhead;
421 static ulonglong my_timer_init_resolution(ulonglong (*this_timer)(
void),
422 ulonglong overhead_times_2)
424 ulonglong time1, time2;
426 int i, jumps, divisible_by_1000, divisible_by_1000000;
428 divisible_by_1000= divisible_by_1000000= 0;
430 for (i= jumps= 0; jumps < 3 && i < MY_TIMER_ITERATIONS * 10; ++
i)
441 if (!(time2 % 1000000))
442 ++divisible_by_1000000;
444 if (best_jump > time2)
447 if (overhead_times_2 == 0)
453 if (jumps == divisible_by_1000000)
455 if (jumps == divisible_by_1000)
458 if (best_jump > overhead_times_2)
472 ulonglong time1, time2, time3, time4;
473 time1= my_timer_cycles();
474 time2= my_timer_microseconds();
476 for (i= 0; i < MY_TIMER_ITERATIONS; ++
i)
478 time3= my_timer_microseconds();
479 if (time3 - time2 > 200)
break;
495 ulonglong (*best_timer)(void);
496 ulonglong best_timer_overhead;
497 ulonglong time1, time2;
502 #if defined(__GNUC__) && defined(__i386__)
504 #elif defined(__SUNPRO_C) && defined(__i386)
506 #elif defined(__GNUC__) && defined(__x86_64__)
508 #elif defined(HAVE_ASM_MSR_H) && defined(HAVE_RDTSCLL)
510 #elif defined(_WIN32) && defined(_M_IX86)
512 #elif defined(_WIN64) && defined(_M_X64)
514 #elif defined(__INTEL_COMPILER) && defined(__ia64__) && defined(HAVE_IA64INTRIN_H)
516 #elif defined(__GNUC__) && defined(__ia64__)
518 #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__POWERPC__) || (defined(_POWER) && defined(_AIX52))) && (defined(__64BIT__) || defined(_ARCH_PPC64))
520 #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__POWERPC__) || (defined(_POWER) && defined(_AIX52))) && (!defined(__64BIT__) && !defined(_ARCH_PPC64))
522 #elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(__sparcv9) && defined(_LP64) && !defined(__SunOS_5_7)
524 #elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(_ILP32) && !defined(__SunOS_5_7)
526 #elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(__i386) && defined(_ILP32)
528 #elif (defined(__SUNPRO_CC) || defined(__SUNPRO_C)) && defined(__x86_64) && defined(_LP64)
530 #elif defined(__GNUC__) && defined(__sparcv9) && defined(_LP64) && (__GNUC__>2)
532 #elif defined(__GNUC__) && defined(__sparc__) && !defined(_LP64) && (__GNUC__>2)
534 #elif defined(__sgi) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_SGI_CYCLE)
536 #elif defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME)
552 #if defined(HAVE_READ_REAL_TIME)
554 #elif defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME)
556 #elif defined(HAVE_CLOCK_GETTIME)
558 #elif defined(__APPLE__) && defined(__MACH__)
573 #if defined(HAVE_GETTIMEOFDAY)
575 #elif defined(_WIN32)
579 if (!QueryPerformanceFrequency(&li))
600 #if defined(HAVE_SYS_TIMEB_H) && defined(HAVE_FTIME)
602 #elif defined(_WIN32)
604 #elif defined(HAVE_TIME)
619 #if defined(HAVE_SYS_TIMES_H) && defined(HAVE_TIMES)
621 #elif defined(_WIN32)
640 best_timer= &my_timer_cycles;
645 best_timer= &my_timer_nanoseconds;
648 best_timer= &my_timer_microseconds;
652 for (i= 0, best_timer_overhead= 1000000000; i < 20; ++
i)
655 time2= best_timer() - time1;
656 if (best_timer_overhead > time2)
657 best_timer_overhead= time2;
663 best_timer_overhead);
667 &my_timer_nanoseconds,
668 best_timer_overhead);
672 &my_timer_microseconds,
673 best_timer_overhead);
677 &my_timer_milliseconds,
678 best_timer_overhead);
683 best_timer_overhead);
695 my_timer_init_resolution(&my_timer_nanoseconds, 20000);
698 my_timer_init_resolution(&my_timer_microseconds, 20);
705 my_timer_init_resolution(&my_timer_milliseconds, 0);
725 MY_TIMER_ROUTINE_QUERYPERFORMANCECOUNTER
731 ulonglong time1, time2;
732 time1= my_timer_init_frequency(mti);
734 time2= my_timer_init_frequency(mti);
754 ulonglong time1, time2, time3, time4;
755 time1= my_timer_cycles();
756 time2= my_timer_milliseconds();
758 for (i= 0; i < MY_TIMER_ITERATIONS * 1000; ++
i)
760 time3= my_timer_milliseconds();
761 if (time3 - time2 > 10)
break;
763 time4= my_timer_cycles();
780 ulonglong time1, time2, time3, time4;
781 time1= my_timer_cycles();
782 time2= my_timer_ticks();
784 for (i= 0; i < MY_TIMER_ITERATIONS * 1000; ++
i)
786 time3= my_timer_ticks();
787 if (time3 - time2 > 10)
break;
789 time4= my_timer_cycles();