Alien-Judy

 view release on metacpan or  search on metacpan

src/judy-1.0.5/test/timeit.h  view on Meta::CPAN

// included it in this section.

#if (JU_HPUX_PA)
#include <machine/reg.h>
#include <sys/pstat.h>

double find_CPU_speed(void);

// Note:  On hpux_*, at least older compilers, it is neither necessary nor even
// allowed to mark the __start_* and __stop_* variables as volatile; the
// compiler does not optimize out the code even without it:

#define	TIMER_vars(T)					 \
	register unsigned long  __start_##T, __stop_##T; \
		 struct timeval __TVBeg_##T, __TVEnd_##T

#define	__START_HRTm(T) _asm("MFCTL", CR_IT, __start_##T)
#define	__END_HRTm(T)   _asm("MFCTL", CR_IT, __stop_##T )

#endif // (JU_HPUX_PA)

// ********************* LINUX IA32 **************************
//
#ifdef JU_LINUX_IA32
#include <asm/msr.h>

double find_CPU_speed(void);

#define	TIMER_vars(T)					 \
	register unsigned long  __start_##T, __stop_##T; \
		 struct timeval __TVBeg_##T, __TVEnd_##T

#define	__START_HRTm(T) rdtscl(__start_##T)
#define	__END_HRTm(T)   rdtscl(__stop_##T)

#endif // JU_LINUX_IA32

// ********************* LINUX_IPF **************************
//
// Define __START_HRTm and __END_HRTm, and also STARTTm and ENDTm in terms of
// the former (no need for gettimeofday()).

#ifdef JU_LINUX_IPF

#include <asm/timex.h>

double find_CPU_speed(void);

// Using cycles_t rather than unsigned long [long] should be more portable;
// and, it appears necessary to mark __start_* and __end_* as volatile so the
// gcc compiler does not optimize out the register access:

#define	TIMER_vars(T)						  \
	register volatile cycles_t	 __start_##T, __stop_##T; \
			  struct timeval __TVBeg_##T, __TVEnd_##T

// This seems required for linux_ia32:


// Older code (see 4.13) used rdtscl(), but this is not portable and does not
// result in a 64-bit value, unlike get_cycles(), which apparently takes
// advantage of a 64-bit control register on both IA32 and IPF => always
// high-res timing with no rollover issues.  Note, cycles_t is unsigned, so the
// math works even in case of a rollover.

#define	__START_HRTm(T)  __start_##T = get_cycles()
#define	__END_HRTm(T)    __stop_##T  = get_cycles()

#define	STARTTm(T)  __START_HRTm(T)
#define	ENDTm(D,T)  { __END_HRTm(T); __HRONLY(D,T); }

#endif // JU_LINUX_IPF


// ********************* WIN IA32 *****************************
//
// WIN IA32 has no way to access the control register (?), so define STARTTm
// and ENDTm directly using clock():

#ifdef JU_WIN_IA32

clock_t TBeg, TEnd;

#define	TIMER_vars(T)  struct timeval __TVBeg_##T, __TVEnd_##T

#define	STARTTm(T)   __TVBeg_##T = clock()
#define	ENDTm(D,T) { __TVEnd_##T = clock(); \
		     (D) = ((double) (__TVEnd_##T - __TVBeg_##T)); }

#endif // JU_WIN_IA32


// ********************* OTHER *****************************
//
// Default to using the low-res, slow-access clock only.

#ifndef TIMER_vars

#define	TIMER_vars(T)  struct timeval __TVBeg_##T, __TVEnd_##T

#define	STARTTm(T)  gettimeofday(&__TVBeg_##T, NULL)

#define	ENDTm(D,T)  gettimeofday(&__TVEnd_##T, NULL);			  \
		    (D) = (((double) __TVEnd_##T.tv_sec * ((double) 1E6)) \
			  + (double) __TVEnd_##T.tv_usec)		  \
			- (((double) __TVBeg_##T.tv_sec * ((double) 1E6)) \
			  + (double) __TVBeg_##T.tv_usec)
#endif // ! TIMER_vars


// COMMON CODE FOR SYSTEMS WITH HIGH-RES CLOCKS (CONTROL REGISTERS):

#ifdef __START_HRTm

// Platforms that define __START_HRTm but not STARTTm (presently only hpux_pa)
// use gettimeofday() for the low-res clock and __START_HRTm/__END_HRTm for
// the high-res clock.  If the low-res clock did not "roll over", use the
// high-res clock; see __HRONLY.
//
// Note:  Rollover is defined conservatively as 1E5 usec (= 1/10 sec).  This
// would require a 40 GHz 32-bit system to be violated.



( run in 0.844 second using v1.01-cache-2.11-cpan-2398b32b56e )