1 .\" Copyright (c) 1985 The Regents of the University of California.
2 .\" All rights reserved.
4 .\" Redistribution and use in source and binary forms, with or without
5 .\" modification, are permitted provided that the following conditions
7 .\" 1. Redistributions of source code must retain the above copyright
8 .\" notice, this list of conditions and the following disclaimer.
9 .\" 2. Redistributions in binary form must reproduce the above copyright
10 .\" notice, this list of conditions and the following disclaimer in the
11 .\" documentation and/or other materials provided with the distribution.
12 .\" 3. All advertising materials mentioning features or use of this software
13 .\" must display the following acknowledgement:
14 .\" This product includes software developed by the University of
15 .\" California, Berkeley and its contributors.
16 .\" 4. Neither the name of the University nor the names of its contributors
17 .\" may be used to endorse or promote products derived from this software
18 .\" without specific prior written permission.
20 .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 .\" @(#)a1.t 5.1 (Berkeley) 4/17/91
34 .ds RH Appendix A \- Benchmark sources
45 \s+2Appendix A \- Benchmark sources\s-2
47 The programs shown here run under 4.2 with only routines
48 from the standard libraries. When run under 4.1 they were augmented
49 with a \fIgetpagesize\fP routine and a copy of the \fIrandom\fP
50 function from the C library. The \fIvforks\fP and \fIvexecs\fP
51 programs are constructed from the \fIforks\fP and \fIexecs\fP programs,
52 respectively, by substituting calls to \fIfork\fP with calls to
59 * System call overhead benchmark.
67 printf("usage: %s #syscalls\n", argv[0]);
70 ncalls = atoi(argv[1]);
80 * Context switching benchmark.
82 * Force system to context switch 2*nsigs
83 * times by forking and exchanging signals.
84 * To calculate system overhead for a context
85 * switch, the signocsw program must be run
86 * with nsigs. Overhead is then estimated by
88 * t2 = time signocsw <n>
89 * overhead = t1 - 2 * t2;
103 printf("usage: %s nsignals\n", argv[0]);
106 nsigs = atoi(argv[1]);
107 signal(SIGALRM, sigsub);
112 kill(otherpid, SIGALRM);
121 signal(SIGALRM, sigsub);
122 kill(otherpid, SIGALRM);
132 * Signal without context switch benchmark.
146 printf("usage: %s nsignals\n", argv[0]);
149 nsigs = atoi(argv[1]);
150 signal(SIGALRM, sigsub);
152 for (i = 0; i < nsigs; i++)
159 signal(SIGALRM, sigsub);
168 * write to self using pipes.
176 register int i, iter;
179 printf("usage: %s iterations message-size\n", argv[0]);
185 msgsize = atoi(*argv);
186 if (msgsize > sizeof (buf) || msgsize <= 0) {
187 printf("%s: Bad message size.\n", *argv);
194 for (i = 0; i < iter; i++) {
195 write(fd[1], buf, msgsize);
196 read(fd[0], buf, msgsize);
206 * write and discard using pipes.
214 register int i, iter;
217 printf("usage: %s iterations message-size\n", argv[0]);
223 msgsize = atoi(*argv);
224 if (msgsize > sizeof (buf) || msgsize <= 0) {
225 printf("%s: Bad message size.\n", *argv);
233 for (i = 0; i < iter; i++)
234 read(fd[0], buf, msgsize);
236 for (i = 0; i < iter; i++)
237 write(fd[1], buf, msgsize);
246 * read and reply using pipes.
248 * Process forks and exchanges messages
249 * over a pipe in a request-response fashion.
256 int fd[2], fd2[2], msgsize;
257 register int i, iter;
260 printf("usage: %s iterations message-size\n", argv[0]);
266 msgsize = atoi(*argv);
267 if (msgsize > sizeof (buf) || msgsize <= 0) {
268 printf("%s: Bad message size.\n", *argv);
280 for (i = 0; i < iter; i++) {
281 read(fd[0], buf, msgsize);
282 write(fd2[1], buf, msgsize);
285 for (i = 0; i < iter; i++) {
286 write(fd[1], buf, msgsize);
287 read(fd2[0], buf, msgsize);
296 * Benchmark program to calculate fork+wait
297 * overhead (approximately). Process
298 * forks and exits while parent waits.
299 * The time to run this program is used
300 * in calculating exec overhead.
306 register int nforks, i;
308 int pid, child, status, brksize;
311 printf("usage: %s number-of-forks sbrk-size\n", argv[0]);
314 nforks = atoi(argv[1]);
316 printf("%s: bad number of forks\n", argv[1]);
319 brksize = atoi(argv[2]);
321 printf("%s: bad size to sbrk\n", argv[2]);
324 cp = (char *)sbrk(brksize);
329 for (i = 0; i < brksize; i += 1024)
331 while (nforks-- > 0) {
339 while ((pid = wait(&status)) != -1 && pid != child)
350 * Benchmark program to calculate exec
351 * overhead (approximately). Process
352 * forks and execs "null" test program.
353 * The time to run the fork program should
354 * then be deducted from this one to
355 * estimate the overhead for the exec.
361 register int nexecs, i;
363 int pid, child, status, brksize;
366 printf("usage: %s number-of-execs sbrk-size job-name\n",
370 nexecs = atoi(argv[1]);
372 printf("%s: bad number of execs\n", argv[1]);
375 brksize = atoi(argv[2]);
377 printf("%s: bad size to sbrk\n", argv[2]);
385 for (i = 0; i < brksize; i += 1024)
387 while (nexecs-- > 0) {
394 execv(argv[3], argv);
398 while ((pid = wait(&status)) != -1 && pid != child)
409 * Benchmark "null job" program.
424 * Benchmark "null big job" program.
426 /* 250 here is intended to approximate vi's text+data size */
427 char space[1024 * 250] = "force into data segment";
442 * Sequential page access benchmark.
444 #include <sys/vadvise.h>
452 register char *pf, *lastpage;
453 int npages = 4096, pagesize, vflag = 0;
461 printf("usage: %s [ -v ] [ -p #pages ] niter\n", name);
464 if (strcmp(*argv, "-p") == 0) {
468 npages = atoi(*argv);
470 printf("%s: Bad page count.\n", *argv);
476 if (strcmp(*argv, "-v") == 0) {
482 pagesize = getpagesize();
483 pages = valloc(npages * pagesize);
484 if (pages == (char *)0) {
485 printf("Can't allocate %d pages (%2.1f megabytes).\n",
486 npages, (npages * pagesize) / (1024. * 1024.));
489 lastpage = pages + (npages * pagesize);
492 for (i = 0; i < niter; i++)
493 for (pf = pages; pf < lastpage; pf += pagesize)
502 * Random page access benchmark.
504 #include <sys/vadvise.h>
512 register int npages = 4096, pagesize, pn, i, niter;
513 int vflag = 0, debug = 0;
521 printf("usage: %s [ -d ] [ -v ] [ -p #pages ] niter\n", name);
524 if (strcmp(*argv, "-p") == 0) {
528 npages = atoi(*argv);
530 printf("%s: Bad page count.\n", *argv);
536 if (strcmp(*argv, "-v") == 0) {
541 if (strcmp(*argv, "-d") == 0) {
547 pagesize = getpagesize();
548 pages = valloc(npages * pagesize);
549 if (pages == (char *)0) {
550 printf("Can't allocate %d pages (%2.1f megabytes).\n",
551 npages, (npages * pagesize) / (1024. * 1024.));
556 for (i = 0; i < niter; i++) {
557 pn = random() % npages;
559 printf("touch page %d\n", pn);
560 pages[pagesize * pn] = 1;
569 * Random page access with
570 * a gaussian distribution.
572 * Allocate a large (zero fill on demand) address
573 * space and fault the pages in a random gaussian
577 float sqrt(), log(), rnd(), cos(), gauss();
584 register int pn, i, niter, delta;
585 register char *pages;
587 int npages = 4096, pagesize, debug = 0;
596 "usage: %s [ -d ] [ -p #pages ] [ -s standard-deviation ] iterations\n", name);
599 if (strcmp(*argv, "-s") == 0) {
603 sscanf(*argv, "%f", &sd);
605 printf("%s: Bad standard deviation.\n", *argv);
611 if (strcmp(*argv, "-p") == 0) {
615 npages = atoi(*argv);
617 printf("%s: Bad page count.\n", *argv);
623 if (strcmp(*argv, "-d") == 0) {
629 pagesize = getpagesize();
630 pages = valloc(npages*pagesize);
631 if (pages == (char *)0) {
632 printf("Can't allocate %d pages (%2.1f megabytes).\n",
633 npages, (npages*pagesize) / (1024. * 1024.));
637 for (i = 0; i < niter; i++) {
638 delta = gauss(sd, 0.0);
639 while (pn + delta < 0 || pn + delta > npages)
640 delta = gauss(sd, 0.0);
643 printf("touch page %d\n", pn);
645 pages[pn * pagesize] = 1;
653 register float qa, qb;
655 qa = sqrt(log(rnd()) * -2.0);
656 qb = 3.14159 * rnd();
657 return (qa * cos(qb) * sd + mean);
664 static int biggest = 0x7fffffff;
666 return ((float)rand(seed) / (float)biggest);