Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Jun 2012 19:51:15 +0300
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        arch@freebsd.org
Subject:   Fast gettimeofday(2) and clock_gettime(2)
Message-ID:  <20120606165115.GQ85127@deviant.kiev.zoral.com.ua>

next in thread | raw e-mail | index | archive | help

--kZU6r8y0YpRwyDfh
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

A positive result from the recent flame-bait on arch@ is the working
implementation of the fast gettimeofday(2) and clock_gettime(2). The
speedup I see is around 6-7x on the 2600K. I think the speedup could
be even bigger on the previous generation of CPUs, where lock
operations and syscall entry are costlier. A sample test runs of
tools/tools/syscall_timing are presented at the end of message.

Patch finds yet another use for the shared page, exporting
time-keeping information for the binuptime(9) algorithm and
re-implementing binuptime(9) in userspace. Kernel directs usermode
whether the rdtsc instruction can be used, there is a global override
sysctl kern.timecounter.fast_gettime to turn it off regardless of
hardware capabilities.

The whole struct vdso_timekeep is versioned, as well as individual
struct vdso_timehands, which should allow to implement future
algorithms without breaking binary compatibility.  The code is
structured to eventually move __vdso_* functions out of libc into
VDSO, if it ever materialize. This desire explains vdso prefix and
header file names.

I implemented and tested the userspace timecounter on amd64, both for
64 and 32 bit binaries, it would probably work for i386 too. Other
architecture maintainers are welcome to add neccessary support there.
You need to provide machine/vdso.h header with definitions of
VDSO_TIMEHANDS_MD fields for struct vdso_timehands, which should
provide information for userspace to implement fast
tc_get_timecount(). The fields are filled in per-arch
cpu_fill_vdso_timehands(9) function. If your architecture support
32bit compat, there are cpu_fill_vdso_timehands32(9) and
VDSO_TIMEHANDS_MD32 to code as well. After that, the
lib/libc/<arch>/sys/__vdso_gettc.c should contain an implemention of
__vdso_gettc() function, exact analogue of tc_get_timecount().

Another potential improvement for the patch is to start using rdtscp
instruction on the CPUs which support it. Then we could correct rdtsc
skews between packages, provided kernel starts maintaining this
information, instead of refusing to activate tsc timecounter. In
particular, on one Nehalem box I see the rdtsc SMP test failing, but
Nehalems do have useful rdtsc, so it is could be fixed later.

Patch is available at http://people.freebsd.org/~kib/misc/moronix.2.patch
It is not a commit candidate yet, since non-x86 architectures are not
handled even at compilation, and i386 is not tested.

sandy% /usr/home/pooma/build/bsd/DEV/stuff/tests/syscall_timing_32 gettimeofday
Clock resolution: 0.000000076
test    loop    time    iterations      periteration
gettimeofday    0       1.000994225     21623297        0.000000046
gettimeofday    1       1.000994980     21596492        0.000000046
gettimeofday    2       1.001070595     21598326        0.000000046
gettimeofday    3       1.000922308     21581398        0.000000046
gettimeofday    4       1.000984264     21605539        0.000000046
gettimeofday    5       1.000989697     21601659        0.000000046
gettimeofday    6       1.000996261     21598385        0.000000046
gettimeofday    7       1.001002223     21583933        0.000000046
gettimeofday    8       1.000985847     21599442        0.000000046
gettimeofday    9       1.000994977     21600935        0.000000046
sandy% sudo sysctl kern.timecounter.fast_gettime=0                            ~
kern.timecounter.fast_gettime: 1 -> 0
sandy% /usr/home/pooma/build/bsd/DEV/stuff/tests/syscall_timing_32 gettimeofday
Clock resolution: 0.000000076
test    loop    time    iterations      periteration
gettimeofday    0       1.001002747     3219274 0.000000310
gettimeofday    1       1.000971052     3220793 0.000000310
gettimeofday    2       1.001067494     3220768 0.000000310
gettimeofday    3       1.000929999     3220812 0.000000310
gettimeofday    4       1.000996106     3217503 0.000000311
gettimeofday    5       1.001058438     3220346 0.000000310
gettimeofday    6       1.000911510     3217308 0.000000311
gettimeofday    7       1.001085906     3220128 0.000000310
gettimeofday    8       1.000920338     3216582 0.000000311
gettimeofday    9       1.000983577     3219559 0.000000310


--kZU6r8y0YpRwyDfh
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (FreeBSD)

iEYEARECAAYFAk/PioMACgkQC3+MBN1Mb4jPzwCfS14QKbr3jY5UhMGJDowJalb/
NrAAoNhv10qQJOytIVY46eOp5IZ3Z9s1
=D2Fs
-----END PGP SIGNATURE-----

--kZU6r8y0YpRwyDfh--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120606165115.GQ85127>