Date: Thu, 27 Oct 2005 16:14:57 -0400 From: Chuck Swiger <cswiger@mac.com> To: "Yuriy N. Shkandybin" <jura@networks.ru> Cc: David Xu <davidxu@freebsd.org>, current@freebsd.org Subject: Timers and timing, was: MySQL Performance 6.0rc1 Message-ID: <43613541.7030009@mac.com> In-Reply-To: <00a801c5dacf$db3b7700$6504010a@Jura> References: <21137.1130401220@critter.freebsd.dk> <00a801c5dacf$db3b7700$6504010a@Jura>
next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------000407080603000304070306 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Yuriy N. Shkandybin wrote: >>> Check gettimeofday syscall, it follows every I/O syscall, I think >>> our gettimeofday is tooooooo expensive, if we can directly get time from >>> memory, the performance will be improved further. > > It's true: > run next on same PC -- freebsd and linux and compare [ ...snippet of timing code deleted, see attachment instead... :-) ] FreeBSD 4.11-STABLE i386 null function: 0.01069 getpid(): 0.51729 time(): 3.51727 gettimeofday(): 3.48715 FreeBSD 5.4-STABLE i386 null function: 0.01278 getpid(): 0.51329 time(): 2.54771 gettimeofday(): 2.54982 Linux 2.6.5 i686 null function: 0.01858 getpid(): 0.01979 time(): 0.44811 gettimeofday(): 0.55776 Darwin 8.2.0 Power Macintosh null function: 0.01889 getpid(): 0.03590 time(): 0.20913 gettimeofday(): 0.17278 SunOS 5.8 sun4u null function: 0.05051 getpid(): 1.29846 time(): 1.26596 gettimeofday(): 0.29507 [ These are representative results (in seconds); running the test three times per host shows the null function time value is stable to two digits, or three on some hosts; the other values seem to vary by less than 10%. ] The Intel boxes are all Intel P3, between 700MHz and 1Ghz, the Sun is a dual-proc E450 @ 450MHz, and the other is a Mac Mini @ 1.3Ghz, I think. Real numbers are are well and good, but I don't want to start yet another thread about microbenchmarks or statistics. People who are doing timers are generally looking for one of two things, a cron-like system which schedules periodic or one-shot events over time intervals of minutes, hours, days, etc (for which time() and alarm() work fine), or they want to deal with high-resolution time in order to see how long a call like a SQL query takes or update the display every 10ms, 16.67ms, and so forth to do realtime graphics (via gettimeofday() and usleep()/nanosleep()). It's clear that the Linux getpid() syscall is merely keeping the pid around locally, rather than doing a full context switch, and Darwin seems to be doing similarly, only with some locking or tracing overhead. It doesn't make sense to keep invoking a hardware clock from the kernel for a timer which is updated at a one-second resolution. Can't we just keep a static time_t called __now in libc for time() to return or stuff into *tloc, which gets updated once in a while (have the scheduler check whether fractional seconds has rolled over every few ticks)? -- -Chuck --------------000407080603000304070306 Content-Type: text/plain; name="timer.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="timer.c" #include <errno.h> #include <stdlib.h> #include <time.h> #include <sys/time.h> typedef void (*null_t) (void); void null_function(void) {} void gettimeofday_(void) { struct timeval unused; gettimeofday(&unused, NULL); } void time_(void) { time_t now = time(&now); } void getpid_(void) { pid_t p = getpid(); } timeit(null_t f, char *name) { struct timeval start; struct timeval stop; struct timeval tmp; int unused; register unsigned i; double diff_time; static double null_time = 0.0; if (null_time == 0.0) { /* null function call */ gettimeofday(&start, NULL); for(i=0; i<1000000; i++) { null_function(); } gettimeofday(&stop, NULL); null_time = (double) (stop.tv_sec - start.tv_sec) * 1.0 + \ (stop.tv_usec - start.tv_usec) / 1000000.0; printf("%20s: %0.5f\n", "null function", null_time); } gettimeofday(&start, NULL); for(i=0; i<1000000; i++) { f(); } gettimeofday(&stop, NULL); diff_time = (double) (stop.tv_sec - start.tv_sec) * 1.0 + \ (stop.tv_usec - start.tv_usec) / 1000000.0; printf("%20s: %0.5f\n", name, diff_time - null_time); } main() { timeit(getpid_, "getpid()"); timeit(time_, "time()"); timeit(gettimeofday_, "gettimeofday()"); } --------------000407080603000304070306--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?43613541.7030009>