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. Neither the name of the University nor the names of its contributors
13 .\" may be used to endorse or promote products derived from this software
14 .\" without specific prior written permission.
16 .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
17 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
20 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 .\" @(#)a1.t 5.1 (Berkeley) 4/17/91
30 .ds RH Appendix A \- Benchmark sources
41 \s+2Appendix A \- Benchmark sources\s-2
43 The programs shown here run under 4.2 with only routines
44 from the standard libraries. When run under 4.1 they were augmented
45 with a \fIgetpagesize\fP routine and a copy of the \fIrandom\fP
46 function from the C library. The \fIvforks\fP and \fIvexecs\fP
47 programs are constructed from the \fIforks\fP and \fIexecs\fP programs,
48 respectively, by substituting calls to \fIfork\fP with calls to
55 * System call overhead benchmark.
63 printf("usage: %s #syscalls\n", argv[0]);
66 ncalls = atoi(argv[1]);
76 * Context switching benchmark.
78 * Force system to context switch 2*nsigs
79 * times by forking and exchanging signals.
80 * To calculate system overhead for a context
81 * switch, the signocsw program must be run
82 * with nsigs. Overhead is then estimated by
84 * t2 = time signocsw <n>
85 * overhead = t1 - 2 * t2;
99 printf("usage: %s nsignals\n", argv[0]);
102 nsigs = atoi(argv[1]);
103 signal(SIGALRM, sigsub);
108 kill(otherpid, SIGALRM);
117 signal(SIGALRM, sigsub);
118 kill(otherpid, SIGALRM);
128 * Signal without context switch benchmark.
142 printf("usage: %s nsignals\n", argv[0]);
145 nsigs = atoi(argv[1]);
146 signal(SIGALRM, sigsub);
148 for (i = 0; i < nsigs; i++)
155 signal(SIGALRM, sigsub);
164 * write to self using pipes.
172 register int i, iter;
175 printf("usage: %s iterations message-size\n", argv[0]);
181 msgsize = atoi(*argv);
182 if (msgsize > sizeof (buf) || msgsize <= 0) {
183 printf("%s: Bad message size.\n", *argv);
190 for (i = 0; i < iter; i++) {
191 write(fd[1], buf, msgsize);
192 read(fd[0], buf, msgsize);
202 * write and discard using pipes.
210 register int i, iter;
213 printf("usage: %s iterations message-size\n", argv[0]);
219 msgsize = atoi(*argv);
220 if (msgsize > sizeof (buf) || msgsize <= 0) {
221 printf("%s: Bad message size.\n", *argv);
229 for (i = 0; i < iter; i++)
230 read(fd[0], buf, msgsize);
232 for (i = 0; i < iter; i++)
233 write(fd[1], buf, msgsize);
242 * read and reply using pipes.
244 * Process forks and exchanges messages
245 * over a pipe in a request-response fashion.
252 int fd[2], fd2[2], msgsize;
253 register int i, iter;
256 printf("usage: %s iterations message-size\n", argv[0]);
262 msgsize = atoi(*argv);
263 if (msgsize > sizeof (buf) || msgsize <= 0) {
264 printf("%s: Bad message size.\n", *argv);
276 for (i = 0; i < iter; i++) {
277 read(fd[0], buf, msgsize);
278 write(fd2[1], buf, msgsize);
281 for (i = 0; i < iter; i++) {
282 write(fd[1], buf, msgsize);
283 read(fd2[0], buf, msgsize);
292 * Benchmark program to calculate fork+wait
293 * overhead (approximately). Process
294 * forks and exits while parent waits.
295 * The time to run this program is used
296 * in calculating exec overhead.
302 register int nforks, i;
304 int pid, child, status, brksize;
307 printf("usage: %s number-of-forks sbrk-size\n", argv[0]);
310 nforks = atoi(argv[1]);
312 printf("%s: bad number of forks\n", argv[1]);
315 brksize = atoi(argv[2]);
317 printf("%s: bad size to sbrk\n", argv[2]);
320 cp = (char *)sbrk(brksize);
325 for (i = 0; i < brksize; i += 1024)
327 while (nforks-- > 0) {
335 while ((pid = wait(&status)) != -1 && pid != child)
346 * Benchmark program to calculate exec
347 * overhead (approximately). Process
348 * forks and execs "null" test program.
349 * The time to run the fork program should
350 * then be deducted from this one to
351 * estimate the overhead for the exec.
357 register int nexecs, i;
359 int pid, child, status, brksize;
362 printf("usage: %s number-of-execs sbrk-size job-name\n",
366 nexecs = atoi(argv[1]);
368 printf("%s: bad number of execs\n", argv[1]);
371 brksize = atoi(argv[2]);
373 printf("%s: bad size to sbrk\n", argv[2]);
381 for (i = 0; i < brksize; i += 1024)
383 while (nexecs-- > 0) {
390 execv(argv[3], argv);
394 while ((pid = wait(&status)) != -1 && pid != child)
405 * Benchmark "null job" program.
420 * Benchmark "null big job" program.
422 /* 250 here is intended to approximate vi's text+data size */
423 char space[1024 * 250] = "force into data segment";
438 * Sequential page access benchmark.
440 #include <sys/vadvise.h>
448 register char *pf, *lastpage;
449 int npages = 4096, pagesize, vflag = 0;
457 printf("usage: %s [ -v ] [ -p #pages ] niter\n", name);
460 if (strcmp(*argv, "-p") == 0) {
464 npages = atoi(*argv);
466 printf("%s: Bad page count.\n", *argv);
472 if (strcmp(*argv, "-v") == 0) {
478 pagesize = getpagesize();
479 pages = valloc(npages * pagesize);
480 if (pages == (char *)0) {
481 printf("Can't allocate %d pages (%2.1f megabytes).\n",
482 npages, (npages * pagesize) / (1024. * 1024.));
485 lastpage = pages + (npages * pagesize);
488 for (i = 0; i < niter; i++)
489 for (pf = pages; pf < lastpage; pf += pagesize)
498 * Random page access benchmark.
500 #include <sys/vadvise.h>
508 register int npages = 4096, pagesize, pn, i, niter;
509 int vflag = 0, debug = 0;
517 printf("usage: %s [ -d ] [ -v ] [ -p #pages ] niter\n", name);
520 if (strcmp(*argv, "-p") == 0) {
524 npages = atoi(*argv);
526 printf("%s: Bad page count.\n", *argv);
532 if (strcmp(*argv, "-v") == 0) {
537 if (strcmp(*argv, "-d") == 0) {
543 pagesize = getpagesize();
544 pages = valloc(npages * pagesize);
545 if (pages == (char *)0) {
546 printf("Can't allocate %d pages (%2.1f megabytes).\n",
547 npages, (npages * pagesize) / (1024. * 1024.));
552 for (i = 0; i < niter; i++) {
553 pn = random() % npages;
555 printf("touch page %d\n", pn);
556 pages[pagesize * pn] = 1;
565 * Random page access with
566 * a gaussian distribution.
568 * Allocate a large (zero fill on demand) address
569 * space and fault the pages in a random gaussian
573 float sqrt(), log(), rnd(), cos(), gauss();
580 register int pn, i, niter, delta;
581 register char *pages;
583 int npages = 4096, pagesize, debug = 0;
592 "usage: %s [ -d ] [ -p #pages ] [ -s standard-deviation ] iterations\n", name);
595 if (strcmp(*argv, "-s") == 0) {
599 sscanf(*argv, "%f", &sd);
601 printf("%s: Bad standard deviation.\n", *argv);
607 if (strcmp(*argv, "-p") == 0) {
611 npages = atoi(*argv);
613 printf("%s: Bad page count.\n", *argv);
619 if (strcmp(*argv, "-d") == 0) {
625 pagesize = getpagesize();
626 pages = valloc(npages*pagesize);
627 if (pages == (char *)0) {
628 printf("Can't allocate %d pages (%2.1f megabytes).\n",
629 npages, (npages*pagesize) / (1024. * 1024.));
633 for (i = 0; i < niter; i++) {
634 delta = gauss(sd, 0.0);
635 while (pn + delta < 0 || pn + delta > npages)
636 delta = gauss(sd, 0.0);
639 printf("touch page %d\n", pn);
641 pages[pn * pagesize] = 1;
649 register float qa, qb;
651 qa = sqrt(log(rnd()) * -2.0);
652 qb = 3.14159 * rnd();
653 return (qa * cos(qb) * sd + mean);
660 static int biggest = 0x7fffffff;
662 return ((float)rand(seed) / (float)biggest);