This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hi I am looking at a problem with the current implementation of HP_TIMING on ia64. The problem is that HP_TIMING uses the ITC (similar to the x86 TSC) which isn't synchronized across nodes, hence in a multi-node NUMA system you can get the situation where HP_TIMING() goes backwards. I fixed this for glibc-2.2 a while ago by making HP_TIMING() call gettimeofday() which is fine (patch below) as with the fast system calls on ia64 it's about 150 cycles. Now my question is what one should do wrt clock_gettime(). The implementation in CVS uses HP_TIMING() for CLOCK_PROCESS_CPUTIME_ID, however I was curious if I could just switch that to calling sys_clock_gettime() directly and then use gettimeofday() as a fall-back? Any oppinions/suggestions? Thanks, Jes 2003-03-21 Jes Sorensen <jes@wildopensource.com> * libc-2.3/sysdeps/ia64/hp-timing.h: Migrate HP_TIMING_NOW() to use gettimeofday(). Adjust HP_TIMING_PRINT() accordingly. * libc-2.3/sysdeps/unix/sysv/linux/ia64/get_clockfreq.c: Timing clock is now in micro seconds, independant of the CPU clock. --- glibc-2.3.2-vanilla/sysdeps/ia64/hp-timing.h Sat Aug 24 20:59:22 2002 +++ glibc-2.3.2/sysdeps/ia64/hp-timing.h Tue Nov 11 07:36:23 2003 @@ -1,5 +1,5 @@ /* High precision, low overhead timing functions. IA-64 version. - Copyright (C) 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 2001. @@ -25,6 +25,7 @@ #include <sys/param.h> #include <stdio-common/_itoa.h> #include <ia64intrin.h> +#include <sys/time.h> /* The macros defined here use the timestamp counter in IA-64. They provide a very accurate way to measure the time with very little @@ -88,15 +89,23 @@ processor implementation. */ #define REPEAT_READ(val) __builtin_expect ((int) val == -1, 0) -/* That's quite simple. Use the `ar.itc' instruction. */ -#define HP_TIMING_NOW(Var) \ - ({ unsigned long int __itc; \ - do \ - asm volatile ("mov %0=ar.itc" : "=r" (__itc) : : "memory"); \ - while (REPEAT_READ (__itc)); \ - Var = __itc; }) +#define HP_TIMING_NOW(Var) (Var = __hp_timing_now()) -/* Use two 'ar.itc' instructions in a row to find out how long it takes. */ +static inline hp_timing_t +__hp_timing_now(void) +{ + hp_timing_t val = 0; + struct timeval tv; + int status; + + status = gettimeofday (&tv, NULL); + if (!status) + val = (hp_timing_t) tv.tv_usec; + + return (hp_timing_t) val; +} + +/* Call twice in a row to find out how long it takes. */ #define HP_TIMING_DIFF_INIT() \ do { \ int __cnt = 5; \ @@ -141,8 +150,8 @@ char *__dest = (Buf); \ while (__len-- > 0 && __cp < __buf + sizeof (__buf)) \ *__dest++ = *__cp++; \ - memcpy (__dest, " clock cycles", MIN (__len, \ - (int) sizeof (" clock cycles"))); \ + memcpy (__dest, " micro seconds", MIN (__len, \ + (int) sizeof (" micro seconds"))); \ } while (0) #endif /* hp-timing.h */ --- glibc-2.3.2-vanilla/sysdeps/unix/sysv/linux/ia64/get_clockfreq.c Sat Jul 7 12:21:34 2001 +++ glibc-2.3.2/sysdeps/unix/sysv/linux/ia64/get_clockfreq.c Tue Nov 11 07:35:28 2003 @@ -1,5 +1,5 @@ /* Get frequency of the system processor. IA-64/Linux version. - Copyright (C) 2001 Free Software Foundation, Inc. + Copyright (C) 2001, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -27,63 +27,5 @@ hp_timing_t __get_clockfreq (void) { - /* We read the information from the /proc filesystem. It contains at - least one line like - itc MHz : 733.390988 - We search for this line and convert the number in an integer. */ - static hp_timing_t result; - int fd; - - /* If this function was called before, we know the result. */ - if (result != 0) - return result; - - fd = open ("/proc/cpuinfo", O_RDONLY); - if (__builtin_expect (fd != -1, 1)) - { - /* XXX AFAIK the /proc filesystem can generate "files" only up - to a size of 4096 bytes. */ - char buf[4096]; - ssize_t n; - - n = read (fd, buf, sizeof buf); - if (__builtin_expect (n, 1) > 0) - { - char *mhz = memmem (buf, n, "itc MHz", 7); - - if (__builtin_expect (mhz != NULL, 1)) - { - char *endp = buf + n; - int seen_decpoint = 0; - int ndigits = 0; - - /* Search for the beginning of the string. */ - while (mhz < endp && (*mhz < '0' || *mhz > '9') && *mhz != '\n') - ++mhz; - - while (mhz < endp && *mhz != '\n') - { - if (*mhz >= '0' && *mhz <= '9') - { - result *= 10; - result += *mhz - '0'; - if (seen_decpoint) - ++ndigits; - } - else if (*mhz == '.') - seen_decpoint = 1; - - ++mhz; - } - - /* Compensate for missing digits at the end. */ - while (ndigits++ < 6) - result *= 10; - } - } - - close (fd); - } - - return result; + return (hp_timing_t) 1000000; }
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |