Path: seismo!harvard!talcott!panda!sources-request From: sources-request@panda.UUCP Newsgroups: mod.sources Subject: speedup for bm on some machines Message-ID: <1523@panda.UUCP> Date: 15 Mar 86 14:33:28 GMT Sender: jpn@panda.UUCP Lines: 110 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 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++; } ----------