Skip to content

Commit

Permalink
gethrtime() is now slower than clock_gettime() on modern Solarisen
Browse files Browse the repository at this point in the history
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
  • Loading branch information
nigoroll committed Oct 5, 2018
1 parent 0742ab0 commit 32e518a
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 4 deletions.
57 changes: 57 additions & 0 deletions configure.ac
Expand Up @@ -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],
Expand Down
9 changes: 5 additions & 4 deletions lib/libvarnish/vtim.c
Expand Up @@ -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;
Expand Down

0 comments on commit 32e518a

Please sign in to comment.