This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH][RFC] Avoid table lookup in isascii, isxdigit.
- From: OndÅej BÃlka <neleai at seznam dot cz>
- To: Carlos O'Donell <carlos at redhat dot com>
- Cc: libc-alpha at sourceware dot org, Siddhesh Poyarekar <siddhesh at redhat dot com>
- Date: Tue, 9 Apr 2013 16:48:45 +0200
- Subject: Re: [PATCH][RFC] Avoid table lookup in isascii, isxdigit.
- References: <20130409115706 dot GA7587 at domone dot kolej dot mff dot cuni dot cz> <5164176B dot 3090100 at redhat dot com>
On Tue, Apr 09, 2013 at 09:28:11AM -0400, Carlos O'Donell wrote:
> On 04/09/2013 07:57 AM, OndÅej BÃlka wrote:
> > Hi, I looked to ctype and thougth if it is possible to decrease table
> > size to 512 bytes. I did not succeed but made following three
> > optimizations.
> >
> > 1. In isdigit use & instead &&. Gcc contains bug that optimizes first
> > but not second case.
> > 2. Refactor isdigit macro
> > 3. Write isxdigit and isascii.
>
> You should add a microbenchmark for isdigit, isascii, and isxdigit :-)
>
I need to do hooking as I did before. This is memory access vs no memory
access situation I do not cache miss rate.
When both access memory with same pattern then microbenchmark suffices
because both are slowed by same (but unknown) amount.
> > Following code is enclosed in
> >
> > #ifndef _ISOMAC
> > # if !defined __NO_CTYPE && !defined NOT_IN_libc
>
> If we are not testing for ISO C compliance, and
> we are not building ctype.c or ctype_l.c, and we
> are building libc...
>
> > Is there reason why we cannot also transform user code in this way?
>
> User code must consult LC_CTYPE to get this correct?
>
Not sure about this
I found in ISO/IEC 9899:TC3 :
7.4.1.12 The isxdigit function
Synopsis
1 #include <ctype.h>
int isxdigit(int c);
Description
2 The isxdigit function tests for any hexadecimal-digit character (as
defined in 6.4.4.1).
Probably I could optimize is* more if I had quaranteee that single byte
locales are ascii compatible. Then we can handle common ascii case
without memory access and call function only when c>=128.
> > ---
> > include/ctype.h | 23 ++++++++++++++++++++---
> > 1 files changed, 20 insertions(+), 3 deletions(-)
> >
> > diff --git a/include/ctype.h b/include/ctype.h
> > index 6a18039..7f9e928 100644
> > --- a/include/ctype.h
> > +++ b/include/ctype.h
> > @@ -56,11 +56,28 @@ __ctype_tolower_loc (void)
> > /* The spec says that isdigit must only match the decimal digits. We
> > can check this without a memory access. */
> > # undef isdigit
> > -# define isdigit(c) ({ int __c = (c); __c >= '0' && __c <= '9'; })
> > +# define isdigit(c) ({ int __c = (c); (__c >= '0') & (__c <= '9'); })
> > # undef isdigit_l
> > -# define isdigit_l(c, l) ({ int __c = (c); __c >= '0' && __c <= '9'; })
> > +# define isdigit_l(c, l) isdigit(c)
> > # undef __isdigit_l
> > -# define __isdigit_l(c, l) ({ int __c = (c); __c >= '0' && __c <= '9'; })
> > +# define __isdigit_l(c, l) isdigit(c)
> > +
> > +/* The spec says that isxdigit must only match the hexadecimal digits. We
> > + can check this without a memory access. */
> > +# undef isxdigit
> > +# define isxdigit(c) ({ int __c = (c); ((__c >= '0') & (__c <= '9')) || ((__c >= 'a') & (__c <= 'f')) || ((__c >= 'A') & (__c <= 'F')); })
> > +# undef isxdigit_l
> > +# define isxdigit_l(c, l) isxdigit(c)
> > +# undef __isxdigit_l
> > +# define __isxdigit_l(c, l) isxdigit(c)
> > +
> > +# undef isascii
> > +# define isascii(c) ({ int __c = (c); (__c & 128 == 0); })
> > +# undef isascii_l
> > +# define isascii_l(c, l) isascii(c)
> > +# undef __isascii_l
> > +# define __isascii_l(c, l) isascii(c)
> > +
> > # endif
> > #endif
> >
> >
>
> Cheers,
> Carlos.
>