Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 29 Dec 2002 00:25:49 +0100 (MET)
From:      Anders Gavare <g@dd.chalmers.se>
To:        freebsd-alpha@freebsd.org
Subject:   faster strlen() using longs (?)
Message-ID:  <Pine.GSO.4.44.0212290009180.18017-100000@elros.dd.chalmers.se>

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

I'm using FreeBSD 4.5 on an Alpha, and I noticed that strlen() isn't
implemented using words, but using chars.

I've experimented with several different variations of using longs, and
this is the fastest one I've come up with. It's a quick hack, I know,
and it's a bit hard coded, so it would have to be placed in the
alpha-specific part of libc.  It is 2.8 times faster than the default
strlen() in libc.


size_t my_strlen3(char *databuf)
{
        long data;
        long *lp;
        size_t len = 0;

	/*  Count non-aligned chars:  */
        while (((size_t) databuf) & (sizeof(long)-1)) {
                if (!*databuf++)
                        return len;
                len++;
        }
        lp = (long *) databuf;

	/*  Loop through full 'long' words:  */
        for (;;) {
		/*  See comment   (START)  */
                data = *lp++;
                if (    ((data & 0xff) == 0) ||
                        ((data & 0xff00) == 0) ||
                        ((data & 0xff0000) == 0) ||
                        ((data & 0xff000000) == 0) ||
                        ((data & 0xff00000000) == 0) ||
                        ((data & 0xff0000000000) == 0) ||
                        ((data & 0xff000000000000) == 0) ||
                        ((data & 0xff00000000000000) == 0)
                    )
                        break;
                len += sizeof(long);
		/*  See comment   (END)  */
        }

	/*  Return the actual length:  */
        if (!(data & 0xff))             return len;
        if (!(data & 0xff00))           return len + 1;
        if (!(data & 0xff0000))         return len + 2;
        if (!(data & 0xff000000))       return len + 3;
        data >>= 32;  len += 4;
        if (!(data & 0xff))             return len;
        if (!(data & 0xff00))           return len + 1;
        if (!(data & 0xff0000))         return len + 2;
        return len + 3;
}


It is sometimes faster when compiled with -O than with -O3 (!), but this
depends on which compiler is used.   The stuff between (START) and (END)
can be #defined and then included multiple times. That way, there will
be multiple word tests before the jump back to the start of the for
loop. This give a small performance gain using some compilers /
compiler options.

If this is not an issue anymore with newer releases of FreeBSD on Alpha,
then just ignore this mail :-)


Anders

PS. I'm not on the list, so please CC me if you feel like replying. DS.


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-alpha" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.GSO.4.44.0212290009180.18017-100000>