This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: How are CPU-optimized libraries supposed to work?


On Sun, Oct 12, 2003 at 01:41:58PM -0400, Daniel Jacobowitz wrote:
> On Fri, Oct 03, 2003 at 04:43:20PM -0700, Roland McGrath wrote:
> > > Oh hm, I didn't realize that HP_TIMING_AVAIL was used for code in
> > > addition to linker statistics etc.
> > 
> > It looks like it's only clock_gettime(CLOCK_*_CPUTIME_ID) that uses it.
> > I've only glanced at the code and don't fully grok how it uses the value,
> > but I do suspect that it matters that it get set early in startup.  But
> > perhaps setting it in libc's initializer if ld.so failed to set it would be
> > good enough.
> > 
> > The other approach is to make a i686-supporting i386-compatible ld.so by
> > hacking it to detect the CPU flavor at runtime early on and do the
> > initialization when possible.
> 
> It does matter that it get set early in startup.  It's used for a
> quick, accurate wall time clock relative to process start time. 
> However, all the spec has to say is:
> 
> Implementations shall also support the special clockid_t value
> CLOCK_PROCESS_CPUTIME_ID, which represents the CPU-time clock of the
> calling process when invoking one of the clock_*() or timer_*()
> functions. For these clock IDs, the values returned by clock_gettime()
> and specified by clock_settime() represent the amount of execution time
> of the process associated with the clock.
> 
> I'm not quite sure that using rdtsc for this is kosher - it looks like
> it's supposed to be a CPU-time clock, not a wall-time clock.  But in
> any case, initializing it a little later doesn't seem like a big deal.
> The difference is about a millisecond on my system.
> 
> With my previous patch:
> Ret: 0 Time: 1116870 sec 181496067 nsec
> 
> With an i686 ld.so:
> Ret: 0 Time: 0 sec 1388670 nsec
> 
> With this patch:
> Ret: 0 Time: 0 sec 125189 nsec
> 
> How's this patch (besides ugly)?

Trivial correction.

> 2003-10-12  Daniel Jacobowitz  <drow@mvista.com>
> 
> 	* sysdeps/generic/ldsodefs.h (struct rtld_global): Include timing
> 	members if HP_TIMING_PAD is defined.
> 	* sysdeps/i386/hp-timing.h: New file.
> 	* elf/Makefile: Add dl-altinit to routines, shared-only-routines.
> 	* elf/dl-altinit.c: New file.
> 
> --- glibc-2.3.2/sysdeps/generic/ldsodefs.h.orig	2003-10-03 11:47:45.000000000 -0400
> +++ glibc-2.3.2/sysdeps/generic/ldsodefs.h	2003-10-03 11:48:10.000000000 -0400
> @@ -292,7 +292,7 @@ struct rtld_global
>    /* The object to be initialized first.  */
>    EXTERN struct link_map *_dl_initfirst;
>  
> -#if HP_TIMING_AVAIL || HP_SMALL_TIMING_AVAIL
> +#if HP_TIMING_AVAIL || HP_SMALL_TIMING_AVAIL || HP_TIMING_PAD
>    /* Start time on CPU clock.  */
>    EXTERN hp_timing_t _dl_cpuclock_offset;
>  
> --- /dev/null	1969-12-31 19:00:00.000000000 -0500
> +++ glibc-2.3.2/sysdeps/i386/hp-timing.h	2003-10-03 11:50:30.000000000 -0400
> @@ -0,0 +1,34 @@
> +/* High precision, low overhead timing functions.  i386 version.
> +   Copyright (C) 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
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, write to the Free
> +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
> +   02111-1307 USA.  */
> +
> +#ifndef _i386_HP_TIMING_H
> +#define _i386_HP_TIMING_H	1
> +
> +#define hp_timing_t hp_timing_t__
> +#include <sysdeps/generic/hp-timing.h>
> +#undef hp_timing_t
> +
> +/* We don't use high-precision timers, but we might load an i686 libpthread
> +   which does.  */
> +#define HP_TIMING_PAD 1
> +
> +/* i686 uses 64bit values for the times.  */
> +typedef unsigned long long int hp_timing_t;
> +
> +#endif	/* hp-timing.h */
> --- glibc-2.3.2/elf/Makefile.orig	2003-10-12 13:15:46.000000000 -0400
> +++ glibc-2.3.2/elf/Makefile	2003-10-12 13:17:38.000000000 -0400
> @@ -23,7 +23,7 @@ subdir		:= elf
>  headers		= elf.h bits/elfclass.h link.h
>  routines	= $(dl-routines) dl-open dl-close dl-support dl-iteratephdr \
>  		  dl-iteratephdr-static dl-addr enbl-secure dl-profstub \
> -		  dl-origin dl-libc dl-sym dl-tsd
> +		  dl-origin dl-libc dl-sym dl-tsd dl-altinit
>  
>  # The core dynamic linking functions are in libc for the static and
>  # profiled libraries.
> @@ -40,6 +40,10 @@ elide-routines.os = $(all-dl-routines) d
>  rtld-routines	:= rtld $(dl-routines) dl-sysdep dl-environ dl-minimal
>  all-rtld-routines = $(rtld-routines) $(sysdep-rtld-routines)
>  
> +# We only need to re-run initializers if ld.so and libc.so might be built
> +# for different machines, so only shared libraries need dl-altinit.
> +shared-only-routines = dl-altinit
> +
>  distribute	:= rtld-Rules \
>  		   $(rtld-routines:=.c) dynamic-link.h do-rel.h dl-machine.h \
>  		   dl-cache.h dl-hash.h soinit.c sofini.c ldd.bash.in \
> @@ -91,7 +95,7 @@ include ../Makeconfig
>  
>  ifeq ($(unwind-find-fde),yes)
>  routines += unwind-dw2-fde-glibc
> -shared-only-routines = unwind-dw2-fde-glibc
> +shared-only-routines += unwind-dw2-fde-glibc
>  endif
>  
>  before-compile  = $(objpfx)trusted-dirs.h
> --- /dev/null	1969-12-31 19:00:00.000000000 -0500
> +++ glibc-2.3.2/elf/dl-altinit.c	2003-10-12 13:23:15.000000000 -0400
> @@ -0,0 +1,43 @@
> +/* Extra initializers for shared libc.
> +   Copyright (C) 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
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, write to the Free
> +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
> +   02111-1307 USA.  */
> +
> +#include <ldsodefs.h>
> +#include <hp-timing.h>
> +
> +/* This file is used from the shared libc, to initialize anything which
> +   ld.so should have initialized but didn't - for instance, if ld.so
> +   is built for a machine without HP_TIMING but libc.so is built for
> +   a machine with HP_TIMING, clock_gettime will expect dl_cpuclock_offset
> +   to be initialized.  */
> +
> +static void
> +dlinit_hptiming (void)
> +{
> +#ifdef HP_TIMING_AVAIL

#if HP_TIMING_AVAIL || HP_SMALL_TIMING_AVAIL

HP_TIMING_AVAIL is always defined...

> +  if (GL(dl_cpuclock_offset) == 0)
> +    HP_TIMING_NOW (GL(dl_cpuclock_offset));
> +#endif
> +}
> +
> +static void dlinit_alt (void) __attribute__((constructor));
> +static void
> +dlinit_alt (void)
> +{
> +  dlinit_hptiming ();
> +}
> 

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]