Pārlūkot izejas kodu

In case CPUs' clocks are not synchronized, we cannot use ticks so we use a
monotonic clock instead.

Cédric Augonnet 16 gadi atpakaļ
vecāks
revīzija
6f1c146e07
3 mainītis faili ar 26 papildinājumiem un 38 dzēšanām
  1. 13 0
      configure.ac
  2. 6 36
      src/common/timing.c
  3. 7 2
      src/common/timing.h

+ 13 - 0
configure.ac

@@ -293,6 +293,9 @@ if test x$use_fxt = xyes; then
 		LDFLAGS="${LDFLAGS} -L$fxtdir/lib/ "
 	fi
 
+	# if we use monotonic clocks, FxT uses -lrt
+	AC_CHECK_LIB(rt, clock_gettime,,AC_MSG_ERROR([cannot find clock_gettime]))
+
 	AC_CHECK_LIB(fxt, fut_setup,,AC_MSG_ERROR([cannot find fxt lib]))
 	AC_CHECK_HEADER([fxt/fxt.h],,AC_MSG_ERROR([cannot find headers for fxt]))
 	AC_CHECK_HEADER([fxt/fut.h],,AC_MSG_ERROR([cannot find headers for fxt]))
@@ -391,6 +394,16 @@ AC_MSG_CHECKING(performance models location)
 AC_MSG_RESULT($perf_model_dir)
 AC_DEFINE_UNQUOTED(PERF_MODEL_DIR, "$perf_model_dir", [performance models location])
 
+# On many multicore CPUs, clock cycles are not synchronized
+AC_ARG_ENABLE(sync-clock, [AS_HELP_STRING([--enable-sync-clock], [Use monotonic clocks])],
+		enable_sync_clock=$enableval, enable_sync_clock=no)
+AC_MSG_CHECKING(whether using a synchronous clock)
+AC_MSG_RESULT($enable_sync_clock)
+AC_DEFINE(USE_SYNC_CLOCK, [1], [Use a mononotic clock])
+if test x$enable_sync_clock = xyes; then
+	AC_CHECK_LIB(rt, clock_gettime,,AC_MSG_ERROR([cannot find clock_gettime]))
+fi
+
 ###############################################################################
 #                                                                             #
 #                                  Examples                                   #

+ 6 - 36
src/common/timing.c

@@ -18,51 +18,21 @@
 
 #ifdef UNRELIABLETICKS
 
-#define TICK_RAW_DIFF(t1, t2) (((t2).tv.tv_sec*1e6 + (t2).tv.tv_usec) + \
-				- ((t1).tv.tv_sec*1e6) + (t1).tv.tv_usec)
-#define TICK_DIFF(t1, t2) (TICK_RAW_DIFF(t1, t2) - residual)
+#define TICK_RAW_DIFF(t1, t2) (((t2).ts.tv_sec*1e9 + (t2).ts.tv_nsec) + \
+				- ((t1).ts.tv_sec*1e9) + (t1).ts.tv_nsec)
+#define TICK_DIFF(t1, t2) (TICK_RAW_DIFF(t1, t2))
 #define TIMING_DELAY(t1, t2) tick2usec(TICK_DIFF(t1, t2))
 
-static double scale = 0.0;
+static double scale = 0;
 static unsigned long long residual = 0;
 
-static int inited = 0;
-
 void timing_init(void)
 {
-  static tick_t t1, t2;
-  int i;
-
-  if (inited) return;
-
-  residual = (unsigned long long)1 << 63;
-  
-  for(i = 0; i < 20; i++)
-    {
-      GET_TICK(t1);
-      GET_TICK(t2);
-      residual = STARPU_MIN(residual, TICK_RAW_DIFF(t1, t2));
-    }
-  
-  {
-    struct timeval tv1,tv2;
-    
-    GET_TICK(t1);
-    gettimeofday(&tv1,0);
-    usleep(500000);
-    GET_TICK(t2);
-    gettimeofday(&tv2,0);
-    scale = ((tv2.tv_sec*1e6 + tv2.tv_usec) -
-	     (tv1.tv_sec*1e6 + tv1.tv_usec)) / 
-      (double)(TICK_DIFF(t1, t2));
-  }
-
-  inited = 1;
 }
 
 inline double tick2usec(long long t)
 {
-  return (double)(t)*scale;
+  return (double)(t)/1000;
 }
 
 inline double timing_delay(tick_t *t1, tick_t *t2)
@@ -75,7 +45,7 @@ inline double timing_now(void)
 	tick_t tick_now;
 	GET_TICK(tick_now);
 
-	return tick2usec(scale*((tick_now).tv.tv_sec*1e6) + (tick_now).tv.tv_usec);
+	return tick2usec(((tick_now).ts.tv_sec*1e9) + (tick_now).ts.tv_usec);
 }
 
 

+ 7 - 2
src/common/timing.h

@@ -32,14 +32,19 @@
 #include <starpu.h>
 
 #ifdef UNRELIABLETICKS
+#include <time.h>
+#ifndef _POSIX_C_SOURCE
+/* for clock_gettime */
+#define _POSIX_C_SOURCE 199309L
+#endif
 
 /* we use the usual gettimeofday method */
 typedef struct tick_s
 {
-	struct timeval tv;
+	struct timespec ts;
 } tick_t;
 
-#define GET_TICK(t) gettimeofday(&((t).tv), NULL)
+#define GET_TICK(t) clock_gettime(CLOCK_MONOTONIC, &((t).ts))
 
 #else // !UNRELIABLETICKS