home *** CD-ROM | disk | FTP | other *** search
- Subject: speedup for bm on some machines
- Newsgroups: mod.sources
- Approved: jpn@panda.UUCP
-
- Mod.sources: Volume 4, Issue 32
- Submitted by: genrad!decvax!utzoo!henry (Henry Spencer)
-
- On some machines with some Unix implementations (PDP11 running V7 for
- example, but there probably are others), bulk data copying from system
- to user space which is not aligned on word boundaries is a terrible
- performance disaster. Bm, Peter Bain's Boyer-Moore grep program, suffers
- from this. Fortunately, it's easy to fix:
-
- 1. In line 43 of Execute.c (this is for bm version 1.2, recently posted),
- change "read" to "xread".
-
- 2. Add the following source file, xread.c, to the compilation.
-
- This code could probably be improved a bit, but as it is it makes a
- difference of a factor of 4 (!) in bm's performance on utzoo.
-
- Henry Spencer @ U of Toronto Zoology
- {allegra,ihnp4,linus,decvax}!utzoo!henry
-
- P.S. I've thrown in a quickie version of bcopy() for people who don't have it.
-
- ----------
- /*
- * Fast-read routine. Tries to do read(2)s at block boundaries on disk, and
- * always does them at word boundaries in core.
- *
- * This code assumes that BUFSIZ is reasonable for internal buffering and
- * that one can test a pointer for alignment by casting to int and ANDing
- * with (sizeof(int)-1).
- */
-
- #include <stdio.h>
-
- static char xbuf[BUFSIZ];
- static int xleft = 0;
- static char *xrest = NULL;
-
- int
- xread(desc, buf, len)
- int desc;
- char *buf;
- int len;
- {
- register int todo;
- register int n;
- char *place;
- int ndone;
- register int ret;
-
- ndone = 0;
- place = buf;
- todo = len;
-
- while (todo > 0) {
- if (xleft > 0) {
- /* Data available in our internal buffer. */
- n = (xleft > todo) ? todo : xleft;
- bcopy(xrest, place, n);
- todo -= n;
- xleft -= n;
- xrest += n;
- ndone += n;
- place += n;
- } else if (todo >= BUFSIZ && (((int)place)&(sizeof(int)-1)) == 0) {
- /* Conditions suitable for a direct read. */
- n = todo / BUFSIZ;
- ret = read(desc, place, n*BUFSIZ);
- if (ret < 0)
- return(ret);
- if (ret == 0)
- return(ndone);
- ndone += ret;
- place += ret;
- todo -= ret;
- } else {
- /* None of the above, refill the internal buffer. */
- ret = read(desc, xbuf, BUFSIZ);
- if (ret < 0)
- return(ret);
- if (ret == 0)
- return(ndone);
- xleft = ret;
- xrest = xbuf;
- }
- }
- return(ndone);
- }
- ----------
- /*
- * bcopy - copy n bytes from a to b
- */
-
- bcopy(a, b, n)
- char *a;
- char *b;
- int n;
- {
- register char *from;
- register char *to;
- register int count;
-
- from = a;
- to = b;
- count = n;
-
- while (--count >= 0)
- *to++ = *from++;
- }
- ----------
-
-
-