summaryrefslogtreecommitdiff
path: root/Timer.C
diff options
context:
space:
mode:
authorDoug Pase <douglas@pase.us>2007-01-22 00:00:00 +0000
committerTim Besard <tim.besard@gmail.com>2011-10-27 16:18:30 +0200
commitfb9ae8907327f93cbeed6ffef914435a4e2ec651 (patch)
tree8432c40e2e646816a83caa83091a105ac08342f6 /Timer.C
Initial commit.
Diffstat (limited to 'Timer.C')
-rw-r--r--Timer.C175
1 files changed, 175 insertions, 0 deletions
diff --git a/Timer.C b/Timer.C
new file mode 100644
index 0000000..d450867
--- /dev/null
+++ b/Timer.C
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2006 International Business Machines Corporation. *
+ * All rights reserved. This program and the accompanying materials *
+ * are made available under the terms of the Common Public License v1.0 *
+ * which accompanies this distribution, and is available at *
+ * http://www.opensource.org/licenses/cpl1.0.php *
+ * *
+ * Contributors: *
+ * Douglas M. pase - initial API and implementation *
+ *******************************************************************************/
+
+
+#include <stdio.h>
+#include <sys/time.h>
+
+#include "Timer.h"
+
+#include "Types.h"
+
+static int64 read_rtc();
+static void calibrate_rtc(int n);
+static double wall_seconds();
+
+static int wall_ticks = -1;
+static int rtc_ticks = -1;
+static double wall_elapsed = -1;
+static int64 rtc_elapsed = -1;
+static double time_factor = -1;
+
+#if !defined(RTC) && !defined(GTOD)
+#define RTC
+#endif
+
+#if defined(RTC)
+
+double
+Timer::seconds()
+{
+ return (double) read_rtc() * time_factor;
+}
+
+int64
+Timer::ticks()
+{
+ // See pg. 406 of the AMD x86-64 Architecture
+ // Programmer's Manual, Volume 2, System Programming
+ unsigned int eax=0, edx=0;
+
+ __asm__ __volatile__(
+ "rdtsc ;"
+ "movl %%eax,%0;"
+ "movl %%edx,%1;"
+ ""
+ : "=r"(eax), "=r"(edx)
+ :
+ : "%eax", "%edx"
+ );
+
+ return ((int64) edx << 32) | (int64) eax;
+}
+
+static int64
+read_rtc()
+{
+ // See pg. 406 of the AMD x86-64 Architecture
+ // Programmer's Manual, Volume 2, System Programming
+ unsigned int eax=0, edx=0;
+
+ __asm__ __volatile__(
+ "rdtsc ;"
+ "movl %%eax,%0;"
+ "movl %%edx,%1;"
+ ""
+ : "=r"(eax), "=r"(edx)
+ :
+ : "%eax", "%edx"
+ );
+
+ return ((int64) edx << 32) | (int64) eax;
+}
+
+void
+Timer::calibrate()
+{
+ Timer::calibrate(1000);
+}
+
+void
+Timer::calibrate(int n)
+{
+ wall_ticks = n;
+
+ double wall_start,wall_finish,t;
+ t = wall_seconds();
+ while (t == (wall_start=wall_seconds())) {
+ ;
+ }
+ int64 rtc_start = read_rtc();
+ for (int i=0; i < wall_ticks; i++) {
+ t = wall_seconds();
+ while (t == (wall_finish=wall_seconds())) {
+ ;
+ }
+ }
+ int64 rtc_finish = read_rtc();
+
+ wall_elapsed = wall_finish - wall_start;
+ rtc_elapsed = rtc_finish - rtc_start;
+ time_factor = wall_elapsed / (double) rtc_elapsed;
+}
+
+static double
+wall_seconds()
+{
+ struct timeval t;
+ gettimeofday(&t, NULL);
+
+ return (double) t.tv_sec + (double) t.tv_usec * 1E-6;
+}
+
+#else
+
+double
+Timer::seconds()
+{
+ struct timeval t;
+ gettimeofday(&t, NULL);
+
+ return (double) t.tv_sec + (double) t.tv_usec * 1E-6;
+}
+
+int64
+Timer::ticks()
+{
+ struct timeval t;
+ gettimeofday(&t, NULL);
+
+ return 1000000 * (int64) t.tv_sec + (int64) t.tv_usec;
+}
+
+void
+Timer::calibrate()
+{
+}
+
+void
+Timer::calibrate(int n)
+{
+}
+
+#endif
+
+static double
+min( double v1, double v2 )
+{
+ if (v2 < v1) return v2;
+ return v1;
+}
+
+double
+Timer::resolution()
+{
+ double a,b,c=1E9;
+ for (int i=0; i < 10; i++) {
+ a = Timer::seconds();
+ while (a == (b=Timer::seconds()))
+ ;
+ a = Timer::seconds();
+ while (a == (b=Timer::seconds()))
+ ;
+ c = min(b - a, c);
+ }
+
+ return c;
+}