diff options
author | Erik Schnetter <schnetter@cct.lsu.edu> | 2007-03-06 01:18:00 +0000 |
---|---|---|
committer | Erik Schnetter <schnetter@cct.lsu.edu> | 2007-03-06 01:18:00 +0000 |
commit | 47389e10db5130c5376ae896c7a78e42dcff23c6 (patch) | |
tree | 122960427b232bacf485f67da074e5cbc4787dda /Carpet/CarpetLib/src/timestat.cc | |
parent | e09d86ff5fd68943fbc79de6535b28033e7a8428 (diff) |
CarpetLib: Add rtc timer on AIX
darcs-hash:20070306011837-dae7b-600bdffcf60d6dff9386180543c3dc7ecf9f4028.gz
Diffstat (limited to 'Carpet/CarpetLib/src/timestat.cc')
-rw-r--r-- | Carpet/CarpetLib/src/timestat.cc | 72 |
1 files changed, 62 insertions, 10 deletions
diff --git a/Carpet/CarpetLib/src/timestat.cc b/Carpet/CarpetLib/src/timestat.cc index 0f2439fec..358ef94ee 100644 --- a/Carpet/CarpetLib/src/timestat.cc +++ b/Carpet/CarpetLib/src/timestat.cc @@ -2,6 +2,7 @@ #include <cassert> #include <cmath> #include <cstdio> +#include <cstdlib> #include <fstream> #include <iomanip> #include <iostream> @@ -15,6 +16,10 @@ #include "cctk_Arguments.h" #include "cctk_Parameters.h" +#ifdef HAVE_SYS_TIME_H +# include <sys/time.h> +#endif + #include "defs.hh" #include "dist.hh" #include "timestat.hh" @@ -27,27 +32,45 @@ namespace CarpetLib { - // A faster timing routine: + // A faster timing routine for i386 processors: // Read the Intel CPU time stamp counter + static + double rdtsc_cputick = 1.0; + static inline double rdtsc () { -#if defined(__i386__) - unsigned long long int val; - __asm__ __volatile__("rdtsc" : "=A" (val) : ); - return val; + // Test for i386 (should use autoconf instead) +#if defined(__i386__) || defined(__x86_64__) + // Serialise using cpuid + // (This is only strictly necessary on some systems) + __asm__ __volatile__("cpuid" : : ); + // Using "=A" does not work on x86_64, where it uses rax instead + // of (edx,eax) + // unsigned long long int val; + // __asm__ __volatile__("rdtsc" : "=A" (val) : ); + unsigned long eax, edx; + asm volatile ("rdtsc" : "=a" (eax), "=d" (edx)); + return rdtsc_cputick * ((unsigned long long) edx << 32 | eax); #else + static bool have_warned = false; + if (not have_warned) { + CCTK_WARN (1, "The Intel rdtsc timer is not supported"); + have_warned = true; + } return 0; #endif } - static - double rdtsc_cputick = 0.0; static void init_rdtsc () { + // Make three warmup measurements + volatile double const rdummy1 = rdtsc (); + volatile double const rdummy2 = rdtsc (); + volatile double const rdummy3 = rdtsc (); double const rstart = rdtsc (); double const wstart = MPI_Wtime (); int const ierr = usleep (1000 * 1000); @@ -56,11 +79,33 @@ namespace CarpetLib { if (ierr) { CCTK_WARN (1, "Could not determine a reliable rdtsc timer resolution"); } - rdtsc_cputick = (wend - wstart) / (rend - rstart); + rdtsc_cputick *= (wend - wstart) / (rend - rstart); } + // A faster timing routine for AIX + static inline + double + rtc () + { + // Test for AIX (should use autoconf instead) +#ifdef __IBMC__ + timebasestruct_t val; + read_real_time (& val, TIMEBASE_SZ); + time_base_to_time (& val, TIMEBASE_SZ); + return val.tb_high + 1.0e-9 * val.tb_low; +#else + static bool have_warned = false; + if (not have_warned) { + CCTK_WARN (1, "The AIX rtc timer not supported"); + have_warned = true; + } + return 0; +#endif + } + + // Call a timer static @@ -68,7 +113,9 @@ namespace CarpetLib { call_timer () { DECLARE_CCTK_PARAMETERS; - enum timer_type { timer_unset, timer_MPI_Wtime, timer_rdtsc, timer_none }; + enum timer_type { + timer_unset, timer_MPI_Wtime, timer_rdtsc, timer_rtc, timer_none + }; static timer_type timer = timer_unset; if (timer == timer_unset) { if (CCTK_EQUALS (timestat_timer, "MPI_Wtime")) { @@ -76,6 +123,8 @@ namespace CarpetLib { } else if (CCTK_EQUALS (timestat_timer, "rdtsc")) { timer = timer_rdtsc; init_rdtsc (); + } else if (CCTK_EQUALS (timestat_timer, "rtc")) { + timer = timer_rtc; } else if (CCTK_EQUALS (timestat_timer, "none")) { timer = timer_none; } else { @@ -86,12 +135,15 @@ namespace CarpetLib { case timer_MPI_Wtime: return MPI_Wtime (); case timer_rdtsc: - return rdtsc_cputick * rdtsc (); + return rdtsc (); + case timer_rtc: + return rtc (); case timer_none: return 0.0; default: assert (0); } + abort (); } |