aboutsummaryrefslogtreecommitdiff
path: root/Carpet/CarpetLib/src/timestat.cc
diff options
context:
space:
mode:
authorErik Schnetter <schnetter@cct.lsu.edu>2007-03-06 01:18:00 +0000
committerErik Schnetter <schnetter@cct.lsu.edu>2007-03-06 01:18:00 +0000
commit47389e10db5130c5376ae896c7a78e42dcff23c6 (patch)
tree122960427b232bacf485f67da074e5cbc4787dda /Carpet/CarpetLib/src/timestat.cc
parente09d86ff5fd68943fbc79de6535b28033e7a8428 (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.cc72
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 ();
}