4.2BSD, while functi
the
perf
a g
the distributed system spent 10-20% m4.1BSD. This added user pr
the
system in a general timesharing envir
Changes made teliminated m
the
added system The creduce the average c
translating a pathname tThese changes reduce the percentage time spent running
in the system by nearly 9%.
The use silhas all
stware interrupt
pr
field ab
ewer interrupts than bef
The kernel
changes, c
ixes, make the system much mrespThe 4.3BSD Berkeley UNIX system ncapable supp4.1BSD while prand file system facilities.
We w
his c
We thank Alan Smith f
a
capability based cache.
We alsGe
int
ixes tdisasters that they caused.
The buffer cache read-ahead trace package was based
implemented several the C library changes. The versi
the Internet daemIn additiwe wideas, inf
Ethernet NetwBerkeley UNIX 4.2BSD,''
Research Rep
CalifBerkeley, December 1984.
tware Perfin Berkeley UNIX 4.2BSD: A Case Study,''
Pr
the Summer Usenix C
erence, PJune 1985, pp. 507-517.
Netw
April 1985.
UNIX CApril 1980.
SRI Internati
the Salt Lake City Usenix C
erence,
pp 228-236, June 1984.
4.2BSD,''
Pr
the Salt Lake City Usenix C
erence,
pp 237-252, June 1984.
the P
erence,
pp 519-531, June 1985.
RFC-883,
N
Oct
erence, January 1980.
C
the paper are available frC
January 1984.
the Salt Lake City Usenix C
erence,
pp 52-61, June 1984.
The prfrwith a getpagesize r
the rand
P
functi
r
Ivf
P and vexecs
pr
r
If
P and execs prrespectively, by substituting calls t
If
P with calls tvf
P.
/*
* System call */
mainmain(argc, argv)
char *argv[];
{
register int ncalls;
if (argc < 2) {
printf("usage: %s #syscalls\n", argv[0]);
exit(1);
}
ncalls = atwhile (ncalls-- > 0)
(v
P) getpid();
}
/* * C * * FI*nsigs * times by f * T
* switch, the sign * with nsigs. Overhead is then estimated by *t1 = time csw <n> *t2 = time sign *
I* t2; */ #include <signal.h> intsigsub(); intintnsigs; mainmain(argc, argv) char *argv[]; { int pid; if (argc < 2) { printf("usage: %s nsignals\n", argv[0]); exit(1); } nsigs = atsignal(SIGALRM, sigsub); pid = fif (pid != 0) { kill(} f
P (;;) sigpause(0); } sigsubsigsub() { signal(SIGALRM, sigsub); kill(if (--nsigs <= 0) exit(0); }
/*
* Signal with */
#include <signal.h>
intpid;
intnsigs;
intsigsub();
mainmain(argc, argv)
char *argv[];
{
register int i;
if (argc < 2) {
printf("usage: %s nsignals\n", argv[0]);
exit(1);
}
nsigs = atsignal(SIGALRM, sigsub);
pid = getpid();
f
P (i = 0; i < nsigs; i++)
kill(pid, SIGALRM);
}
sigsubsigsub()
{
signal(SIGALRM, sigsub);
}
/* * IPC benchmark, * write tusing pipes. */ mainmain(argc, argv) char *argv[]; { char buf[512]; int fd[2], msgsize; register int i, iter; if (argc < 3) { printf("usage: %s iteratiexit(1); } argc--, argv++; iter = at
I*argv); argc--, argv++; msgsize = at
I*argv); if (msgsize > size (buf) || msgsize <= 0) { printf("%s: Bad message size.\n", *argv); exit(2); } if (pipe(fd) < 0) { perrexit(3); } f
P (i = 0; i < iter; i++) { write(fd[1], buf, msgsize); read(fd[0], buf, msgsize); } }
/*
* IPC benchmarkl,
* write and discard using pipes.
*/
mainmain(argc, argv)
char *argv[];
{
char buf[512];
int fd[2], msgsize;
register int i, iter;
if (argc < 3) {
printf("usage: %s iteratiexit(1);
}
argc--, argv++;
iter = at
I*argv);
argc--, argv++;
msgsize = at
I*argv);
if (msgsize > size (buf) || msgsize <= 0) {
printf("%s: Bad message size.\n", *argv);
exit(2);
}
if (pipe(fd) < 0) {
perrexit(3);
}
if (ff
P (i = 0; i < iter; i++)
read(fd[0], buf, msgsize);
else
f
P (i = 0; i < iter; i++)
write(fd[1], buf, msgsize);
}
/* * IPC benchmark, * read and reply using pipes. * * Pr*
ashi */ mainmain(argc, argv) char *argv[]; { char buf[512]; int fd[2], fd2[2], msgsize; register int i, iter; if (argc < 3) { printf("usage: %s iteratiexit(1); } argc--, argv++; iter = at
I*argv); argc--, argv++; msgsize = at
I*argv); if (msgsize > size (buf) || msgsize <= 0) { printf("%s: Bad message size.\n", *argv); exit(2); } if (pipe(fd) < 0) { perrexit(3); } if (pipe(fd2) < 0) { perrexit(3); } if (ff
P (i = 0; i < iter; i++) { read(fd[0], buf, msgsize); write(fd2[1], buf, msgsize); } else f
P (i = 0; i < iter; i++) { write(fd[1], buf, msgsize); read(fd2[0], buf, msgsize); } }
/* * Benchmark pr* * f * The time t * in calculating exec */ mainmain(argc, argv) char *argv[]; { register int nfchar *cp; int pid, child, status, brksize; if (argc < 2) { printf("usage: %s number--fexit(1); } nfif (nf
3{ printf("%s: bad number fexit(2); } brksize = atif (brksize < 0) { printf("%s: bad size texit(3); } cp = (char *)sbrk(brksize); if ((int)cp == -1) { perrexit(4); } f
P (i = 0; i < brksize; i += 1024) cp[i] = i; while (nf
3{ child = fif (child == -1) { perr
exit(-1); } if (child == 0) -exit(-1); while ((pid = wait(&status)) != -1 && pid != child) ; } exit(0); }
/* * Benchmark pr * * f * The time t* then be deducted fr * estimate the
*/ mainmain(argc, argv) char *argv[]; { register int nexecs, i; char *cp, *sbrk(); int pid, child, status, brksize; if (argc < 3) { printf("usage: %s number--execs sbrk-size j argv[0]); exit(1); } nexecs = atif (nexecs < 0) { printf("%s: bad number execs\n", argv[1]); exit(2); } brksize = atif (brksize < 0) { printf("%s: bad size texit(3); } cp = sbrk(brksize); if ((int)cp == -1) { perrexit(4); } f
P (i = 0; i < brksize; i += 1024) cp[i] = i; while (nexecs-- > 0) { child = fif (child == -1) { perr
exit(-1); } if (child == 0) { execv(argv[3], argv); perr-exit(-1); } while ((pid = wait(&status)) != -1 && pid != child) ; } exit(0); }
/*
* Benchmark "null j */
mainmain(argc, argv)
char *argv[];
{
exit(0);
}
/* * Benchmark "null big j */ /* 250 here is intended tI*/ charspace[1024 * 250] = "f mainmain(argc, argv) char *argv[]; { exit(0); }
/*
* Sequential page access benchmark.
*/
#include <sys/vadvise.h>
char*vall
mainmain(argc, argv)
char *argv[];
{
register i, niter;
register char *pf, *lastpage;
int npages = 4096, pagesize, vflag = 0;
char *pages, *name;
name = argv[0];
argc--, argv++;
again:
if (argc < 1) {
usage:
printf("usage: %s [ -v ] [ -p #pages ] niter\n", name);
exit(1);
}
if (strcmp(*argv, "-p") == 0) {
argc--, argv++;
if (argc < 1)
g
P usage;
npages = at
I*argv);
if (npages <= 0) {
printf("%s: Bad page c
I*argv);
exit(2);
}
argc--, argv++;
g
P again;
}
if (strcmp(*argv, "-v") == 0) {
argc--, argv++;
vflag++;
g
P again;
}
niter = at
I*argv);
pagesize = getpagesize();
pages = vall
I* pagesize);
if (pages == (char *)0) {
printf("Can't all
megabytes).\n",
npages, (npages * pagesize) / (1024. * 1024.));
exit(3);
}
lastpage = pages + (npages * pagesize);
if (vflag)
vadvise(VA-SEQL);
f
P (i = 0; i < niter; i++)
f
P (pf = pages; pf < lastpage; pf += pagesize)
*pf = 1;
}
/*
* Rand */
#include <sys/vadvise.h>
char*vallintrand();
mainmain(argc, argv)
char *argv[];
{
register int npages = 4096, pagesize, pn, i, niter;
int vflag = 0, debug = 0;
char *pages, *name;
name = argv[0];
argc--, argv++;
again:
if (argc < 1) {
usage:
printf("usage: %s [ -d ] [ -v ] [ -p #pages ] niter\n", name);
exit(1);
}
if (strcmp(*argv, "-p") == 0) {
argc--, argv++;
if (argc < 1)
g
P usage;
npages = at
I*argv);
if (npages <= 0) {
printf("%s: Bad page c
I*argv);
exit(2);
}
argc--, argv++;
g
P again;
}
if (strcmp(*argv, "-v") == 0) {
argc--, argv++;
vflag++;
g
P again;
}
if (strcmp(*argv, "-d") == 0) {
argc--, argv++;
debug++;
g
P again;
}
niter = at
I*argv);
pagesize = getpagesize();
pages = vall
I* pagesize);
if (pages == (char *)0) {
printf("Can't all
megabytes).\n",
npages, (npages * pagesize) / (1024. * 1024.));
exit(3);
}
if (vflag)
vadvise(VA-ANOM);
f
P (i = 0; i < niter; i++) {
pn = randif (debug)
printf("tpages[pagesize * pn] = 1;
}
}
/* * Rand * a gaussian distributi * * Allill * space and fault the pages in a rand * */ fl
Psqrt(), lchar*vallintrand(); mainmain(argc, argv) char *argv[]; { register int pn, i, niter, delta; register char *pages; fl
P sd = 10.0; int npages = 4096, pagesize, debug = 0; char *name; name = argv[0]; argc--, argv++; again: if (argc < 1) { usage: printf( "usage: %s [ -d ] [ -p #pages ] [ -s standard-deviatiexit(1); } if (strcmp(*argv, "-s") == 0) { argc--, argv++; if (argc < 1) g
P usage; sscanf(*argv, "%f", &sd); if (sd <= 0) { printf("%s: Bad standard deviati
I*argv); exit(2); } argc--, argv++; g
P again; } if (strcmp(*argv, "-p") == 0) { argc--, argv++; if (argc < 1) g
P usage; npages = at
I*argv); if (npages <= 0) { printf("%s: Bad page c
I*argv); exit(2); } argc--, argv++; g
P again; } if (strcmp(*argv, "-d") == 0) { argc--, argv++; debug++; g
P again; } niter = at
I*argv); pagesize = getpagesize(); pages = vall
I*pagesize); if (pages == (char *)0) { printf("Can't all
megabytes).\n", npages, (npages*pagesize) / (1024. * 1024.)); exit(3); } pn = 0; f
P (i = 0; i < niter; i++) { delta = gauss(sd, 0.0); while (pn + delta < 0 || pn + delta > npages) delta = gauss(sd, 0.0); pn += delta; if (debug) printf("telse pages[pn * pagesize] = 1; } } fl
P gaussgauss(sd, mean) fl
P sd, mean; { register fl
P qa, qb; qa = sqrt(l
I* -2.0); qb = 3.14159 * rnd(); return (qa * c
I* sd + mean); } fl
P rndrnd() { static int seed = 1; static int biggest = 0x7fffffff; return ((fl
P)rand(seed) / (fl
P)biggest); }
#! /bin/csh -fx # Script t# date make clean; time make time syscall 100000 time seqpage -p 7500 10 time seqpage -v -p 7500 10 time randpage -p 7500 30000 time randpage -v -p 7500 30000 time gausspage -p 7500 -s 1 30000 time gausspage -p 7500 -s 10 30000 time gausspage -p 7500 -s 30 30000 time gausspage -p 7500 -s 40 30000 time gausspage -p 7500 -s 50 30000 time gausspage -p 7500 -s 60 30000 time gausspage -p 7500 -s 80 30000 time gausspage -p 7500 -s 10000 30000 time csw 10000 time signtime pipeself 10000 512 time pipeself 10000 4 time udgself 10000 512 time udgself 10000 4 time pipediscard 10000 512 time pipediscard 10000 4 time udgdiscard 10000 512 time udgdiscard 10000 4 time pipeback 10000 512 time pipeback 10000 4 time udgback 10000 512 time udgback 10000 4 size ftime ftime ftime fsize vftime vftime vftime vfcsize nulljtime execs 1000 0 nulljtime execs 1000 1024 nulljtime execs 1000 102400 nulljtime vexecs 1000 0 nulljtime vexecs 1000 1024 nulljtime vexecs 1000 102400 nulljsize bigjtime execs 1000 0 bigjtime execs 1000 1024 bigjtime execs 1000 102400 bigjtime vexecs 1000 0 bigjtime vexecs 1000 1024 bigjtime vexecs 1000 102400 bigj# fill envirsetenv a 012345678901234567890123456789012345678901234567890123456780123456789 setenv b 012345678901234567890123456789012345678901234567890123456780123456789 setenv c 012345678901234567890123456789012345678901234567890123456780123456789 setenv d 012345678901234567890123456789012345678901234567890123456780123456789 setenv e 012345678901234567890123456789012345678901234567890123456780123456789 setenv f 012345678901234567890123456789012345678901234567890123456780123456789 setenv g 012345678901234567890123456789012345678901234567890123456780123456789 setenv h 012345678901234567890123456789012345678901234567890123456780123456789 setenv i 012345678901234567890123456789012345678901234567890123456780123456789 setenv j 012345678901234567890123456789012345678901234567890123456780123456789 setenv k 012345678901234567890123456789012345678901234567890123456780123456789 setenv l 012345678901234567890123456789012345678901234567890123456780123456789 setenv m 012345678901234567890123456789012345678901234567890123456780123456789 setenv n 012345678901234567890123456789012345678901234567890123456780123456789 setenv ctime execs 1000 0 nulljtime execs 1000 1024 nulljtime execs 1000 102400 nulljtime execs 1000 0 bigjtime execs 1000 1024 bigjtime execs 1000 102400 bigj