[6.0] f6a34391d gethrtime() is now slower than clock_gettime() on modern Solarisen
Dridi Boukelmoune
dridi.boukelmoune at gmail.com
Wed Oct 31 13:08:27 UTC 2018
commit f6a34391d1e2a7529dec4c810b2d2799169e8dcf
Author: Nils Goroll <nils.goroll at uplex.de>
Date: Fri Oct 5 12:25:42 2018 +0200
gethrtime() is now slower than clock_gettime() on modern Solarisen
Throw out the conventional wisdom and base the decision on a micro
benchmark.
clock_gettime() is now preferred if it is consistently at least
double as fast as gethrtime(), which is the case on varnishdev-il,
the SmartOS vtest machine.
config.log gives details on the performance check, sample output
below:
configure:22703: ./conftest
hrtime 45989530 check 16748699083977959327
clock_gettime 4119385 check 16748701613138517215
...
hrtime 48113108 check 16748749015170035860
clock_gettime 4020802 check 16748751585081458308
clock_gettime wins 10/10
diff --git a/configure.ac b/configure.ac
index 00172c7cc..f32b8db3f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -355,6 +355,63 @@ AC_CHECK_FUNCS([clock_gettime])
AC_CHECK_FUNCS([gethrtime])
LIBS="${save_LIBS}"
+if test "x$ac_cv_func_gethrtime" = xyes && \
+ test "x$ac_cv_func_clock_gettime" = xyes ; then
+ AC_MSG_CHECKING(if clock_gettime is faster than gethrtime)
+ AC_RUN_IFELSE(
+ [AC_LANG_PROGRAM([[
+#include <sys/time.h>
+#include <time.h>
+#include <stdio.h>
+
+static hrtime_t cl()
+{
+ struct timespec ts;
+
+ (void) clock_gettime(CLOCK_MONOTONIC, &ts);
+ return (ts.tv_sec * 1e9 + ts.tv_nsec);
+}
+ ]],[[
+ hrtime_t s, c, e, t_hr, t_cl;
+ int i, r, wins;
+
+ wins = 0;
+ for (r = 0; r < 10; r++) {
+ c = 0;
+ s = gethrtime();
+ for (i=0; i<100000; i++)
+ c += gethrtime();
+ e = gethrtime();
+ t_hr = e - s;
+ fprintf(stderr, "hrtime\t\t%12lu check %lu\n",
+ (unsigned long)t_hr, (unsigned long)c);
+
+ c = 0;
+ s = gethrtime();
+ for (i=0; i<100000; i++)
+ c += cl();
+ e = gethrtime();
+ t_cl = e - s;
+ fprintf(stderr, "clock_gettime\t%12lu check %lu\n",
+ (unsigned long)t_cl, (unsigned long)c);
+
+ if (t_cl * 2 < t_hr)
+ wins++;
+ }
+ fprintf(stderr, "clock_gettime wins %d/%d\n", wins, r);
+ if (2 * wins >= r)
+ return (0);
+ return (1);
+ ]])],
+ [AC_MSG_RESULT(yes)
+ AC_DEFINE([USE_GETHRTIME], [0], [whether to use gethrtime])
+ ],
+ [AC_MSG_RESULT(no)
+ AC_DEFINE([USE_GETHRTIME], [1], [whether to use gethrtime])
+ ]
+ )
+fi
+
# --enable-kqueue
AC_ARG_ENABLE(kqueue,
AS_HELP_STRING([--enable-kqueue],
diff --git a/lib/libvarnish/vtim.c b/lib/libvarnish/vtim.c
index f9de6244e..39d5ca342 100644
--- a/lib/libvarnish/vtim.c
+++ b/lib/libvarnish/vtim.c
@@ -118,15 +118,16 @@ init(void)
#endif
/*
- * Note on Solaris: for some reason, clock_gettime(CLOCK_MONOTONIC, &ts) is not
- * implemented in assembly, but falls into a syscall, while gethrtime() doesn't,
- * so we save a syscall by using gethrtime() if it is defined.
+ * On older Solaris-incarnations, gethrtime() was faster than
+ * clock_gettime(CLOCK_MONOTONIC). Our configure script prefers
+ * clock_gettime if it is consistently at least twice as fast as
+ * gethrtime(), which is the case on modern Solaris descendents.
*/
double
VTIM_mono(void)
{
-#ifdef HAVE_GETHRTIME
+#if defined(HAVE_GETHRTIME) && USE_GETHRTIME
return (gethrtime() * 1e-9);
#elif HAVE_CLOCK_GETTIME
struct timespec ts;
More information about the varnish-commit
mailing list