From 34720c47f1d164803e1d75de350f987c7b61b75d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Fri, 7 Jan 2005 15:28:48 +0000 Subject: [PATCH] Added kernel benchmarks from bsd The purpose is to compare Haiku and BeOS R5 on specific operations git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10605 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/tests/kernel/Jamfile | 1 + src/tests/kernel/benchmarks/Jamfile | 22 +++ src/tests/kernel/benchmarks/ctxbench.c | 212 +++++++++++++++++++++ src/tests/kernel/benchmarks/execbench.c | 52 +++++ src/tests/kernel/benchmarks/forkbench.c | 70 +++++++ src/tests/kernel/benchmarks/memspeed.c | 83 ++++++++ src/tests/kernel/benchmarks/syscallbench.c | 51 +++++ 7 files changed, 491 insertions(+) create mode 100644 src/tests/kernel/benchmarks/Jamfile create mode 100644 src/tests/kernel/benchmarks/ctxbench.c create mode 100644 src/tests/kernel/benchmarks/execbench.c create mode 100644 src/tests/kernel/benchmarks/forkbench.c create mode 100644 src/tests/kernel/benchmarks/memspeed.c create mode 100644 src/tests/kernel/benchmarks/syscallbench.c diff --git a/src/tests/kernel/Jamfile b/src/tests/kernel/Jamfile index 42c2115bba..18d91dba77 100644 --- a/src/tests/kernel/Jamfile +++ b/src/tests/kernel/Jamfile @@ -3,3 +3,4 @@ SubDir OBOS_TOP src tests kernel ; SubInclude OBOS_TOP src tests kernel boot ; SubInclude OBOS_TOP src tests kernel core ; SubInclude OBOS_TOP src tests kernel libroot ; +SubInclude OBOS_TOP src tests kernel benchmarks ; diff --git a/src/tests/kernel/benchmarks/Jamfile b/src/tests/kernel/benchmarks/Jamfile new file mode 100644 index 0000000000..6c0ba5e08e --- /dev/null +++ b/src/tests/kernel/benchmarks/Jamfile @@ -0,0 +1,22 @@ +SubDir OBOS_TOP src tests kernel benchmarks ; + +SimpleTest memspeedTest : + memspeed.c +; + +SimpleTest syscallbenchTest : + syscallbench.c +; + +SimpleTest ctxbenchTest : + ctxbench.c +; + +SimpleTest execbenchTest : + execbench.c +; + +SimpleTest forkbenchTest : + forkbench.c +; + diff --git a/src/tests/kernel/benchmarks/ctxbench.c b/src/tests/kernel/benchmarks/ctxbench.c new file mode 100644 index 0000000000..e4597c37d9 --- /dev/null +++ b/src/tests/kernel/benchmarks/ctxbench.c @@ -0,0 +1,212 @@ +/* + * gcc -Wall -Werror -O3 -static -o ctx ctx.c + */ + +#define errx(x,y...) { fprintf(stderr, y); fprintf(stderr, "\n"); exit(x); } + +#include +#include +#include +#include +#include +#if defined (LWP) +#include +#include +#endif + +#define ITERATIONS 8192 +#define PASSES 50 + +int fd0[2], fd1[2]; +unsigned long elapsed_times[ITERATIONS]; +unsigned long overhead; +pid_t childpid; + +static void +usage(void) +{ + printf("ctx [-hl]\n"); + exit(1); +} + +static void +child(void) +{ + int ch; + + ch = 0; + if (write(fd1[1], &ch, 1) != 1) + errx(1, "child write failed"); + while (1) { + if (read(fd0[0], &ch, 1) != 1) + errx(1, "child read failed"); + if (write(fd1[1], &ch, 1) != 1) + errx(1, "child write failed"); + } +} + +static void +dump_results(void) +{ + unsigned long min_time, max_time, sum; + int i; + + min_time = elapsed_times[0]; + max_time = elapsed_times[0]; + sum = 0; + for (i=1; i max_time) + max_time = elapsed_times[i]; + sum += elapsed_times[i] - overhead; + } + min_time -= overhead; + max_time -= overhead; + + printf("min latency: %f\n", (double)min_time / PASSES); + printf("max latency: %f\n", (double)max_time / PASSES); + printf("mean latency: %f\n", (double)sum / ITERATIONS / PASSES); +} + +int +main(int argc, char *argv[]) +{ + int i, ch, count; + struct timeval before, after; + unsigned long elapsed; + int use_lwps = 0; + + memset(elapsed_times, 0, ITERATIONS); + + while ((ch = getopt(argc, argv, "hl")) != -1) { + switch (ch) { + case 'l': +#if defined(LWP) + use_lwps = 1; +#else + errx(1, "not supported"); +#endif + break; + case 'h': + usage(); + } + } + argc -= optind; + argv += optind; + + sleep(1); + + if (pipe(fd0) != 0) + errx(1, "Unable to create pipe"); + if (pipe(fd1) != 0) + errx(1, "Unable to create pipe"); + + /* + * Determine overhead + */ + for (count=0; count<2; count++) { + gettimeofday(&before, NULL); + for (i=0; i<2*(PASSES/2); i++) { + ch = 0; + write(fd0[1], &ch, 1); + read(fd0[0], &ch, 1); + } + gettimeofday(&after, NULL); + overhead = 1000000 * (after.tv_sec - before.tv_sec); + overhead += after.tv_usec - before.tv_usec; + } + + if (use_lwps) { +#if defined(LWP) + ucontext_t u; + ucontext_t *contextp; + int stacksize = 65536; + void *stackbase; + lwpid_t l; + int error; + + getcontext(&u); + contextp = (ucontext_t *)malloc(sizeof(ucontext_t)); + stackbase = malloc(stacksize); + sigprocmask(SIG_SETMASK, NULL, &contextp->uc_sigmask); + _lwp_makecontext(contextp, child, NULL, NULL, + stackbase, stacksize); + error = _lwp_create(contextp, 0, &l); + if (error) + errx(1, "error _lwp_create"); +#endif + } else { + switch (childpid = fork()) { + case 0: /* child */ + child(); + case -1: /* error */ + errx(1, "error forking"); + break; + } + } + + ch = 0; + if (read(fd1[0], &ch, 1) != 1) + errx(1, "parent read failed"); + for (count=0; count +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + struct timeval before, after; + unsigned long time, elapsed; + char timestr[12], iterstr[12]; + char *timeptr, *countptr; + int iter, count; + + if (argc < 2) + errx(1, "Usage: %s iterations", argv[0]); + + iter = atoi(argv[1]); + if (iter > 0) { + gettimeofday(&before, NULL); + time = 1000000 * before.tv_sec + before.tv_usec; + sprintf(timestr,"%lu", time); + timeptr = timestr; + countptr = argv[1]; + } else { + iter = atoi(argv[2]); + timeptr = argv[3]; + countptr = argv[4]; + } + + if (iter != 0) { + iter--; + sprintf(iterstr, "%d", iter); + execl(argv[0], argv[0], "0", iterstr, timeptr, countptr, NULL); + errx(1, "execl failed"); + } + + gettimeofday(&after, NULL); + sscanf(argv[3],"%lu", &time); + count = atoi(argv[4]); + elapsed = 1000000 * after.tv_sec + after.tv_usec; + elapsed -= time; + + printf("time: %lu microseconds\n", elapsed / count); + + return (1); +} diff --git a/src/tests/kernel/benchmarks/forkbench.c b/src/tests/kernel/benchmarks/forkbench.c new file mode 100644 index 0000000000..2fadc1160e --- /dev/null +++ b/src/tests/kernel/benchmarks/forkbench.c @@ -0,0 +1,70 @@ +/* + * from ftp://ftp.netbsd.org/pub/NetBSD/misc/gmcgarry/bench/forkbench.tar.gz + */ + +/* From 4.4 BSD sys/tests/benchmarks/forks.c. */ + +#include +#include +#include +#include +#include + +/* + * Benchmark program to calculate fork+wait + * overhead (approximately). Process + * forks and exits while parent waits. + * The time to run this program is used + * in calculating exec overhead. + */ + +int +main(argc, argv) + char *argv[]; +{ + int nforks, i; + char *cp; + int pid, child, status, brksize; + struct timeval before, after; + unsigned elapsed; + + if (argc < 3) { + printf("usage: %s number-of-forks sbrk-size\n", argv[0]); + exit(1); + } + nforks = atoi(argv[1]); + if (nforks < 0) { + printf("%s: bad number of forks\n", argv[1]); + exit(2); + } + brksize = atoi(argv[2]); + if (brksize < 0) { + printf("%s: bad size to sbrk\n", argv[2]); + exit(3); + } + + gettimeofday(&before, NULL); + cp = (char *)sbrk(brksize); + if (cp == (void *)-1) { + perror("sbrk"); + exit(4); + } + for (i = 0; i < brksize; i += 1024) + cp[i] = i; + for (i=0; i +#include +#include +#include +#include +#include + +#define KB (1024) +#define MB (KB*KB) + +#define TESTSIZE (8*MB) +#define LOOPSIZE (256*MB) + +int main(int argc, char *argv[]) +{ + u_long mb = TESTSIZE; + u_long size, passes, d, i, j; + volatile u_long *mem; + struct tms tms; + time_t start, stop; + + switch (argc) { + case 2: + mb = atol(argv[1])*MB; + case 1: + break; + + default: + fprintf(stderr, "Usage: %s megabytes\n", argv[0]); + exit(1); + break; + } + + mem = malloc(mb); + + fprintf(stderr, "*** MEMORY WRITE PERFORMANCE (%d MB LOOP) ***\n", + LOOPSIZE/MB); + for (size = 64; size <= mb; size <<= 1) { + passes = LOOPSIZE/size; + fprintf(stderr, "size = %9ld bytes: ", size); + times(&tms); + start = tms.tms_utime; + for (i = 0; i < passes; i++) + for (j = 0; j < size/sizeof(u_long); j += 16) { + mem[j] = 0; mem[j+1] = 0; mem[j+2] = 0; mem[j+3] = 0; + mem[j+4] = 0; mem[j+5] = 0; mem[j+6] = 0; mem[j+7] = 0; + mem[j+8] = 0; mem[j+9] = 0; mem[j+10] = 0; mem[j+11] = 0; + mem[j+12] = 0; mem[j+13] = 0; mem[j+14] = 0; mem[j+15] = 0; + } + times(&tms); + stop = tms.tms_utime; + fprintf(stderr, "%5.3f MB/s\n", + (double)(LOOPSIZE/MB)/(double)(stop-start)*(double)CLK_TCK); + } + fprintf(stderr, "*** MEMORY READ PERFORMANCE (%d MB LOOP) ***\n", + LOOPSIZE/MB); + for (size = 64; size <= mb; size <<= 1) { + passes = LOOPSIZE/size; + fprintf(stderr, "size = %9ld bytes: ", size); + times(&tms); + start = tms.tms_utime; + for (i = 0; i < passes; i++) + for (j = 0; j < size/sizeof(u_long); j += 16) { + d = mem[j]; d = mem[j+1]; d = mem[j+2]; d = mem[j+3]; + d = mem[j+4]; d = mem[j+5]; d = mem[j+6]; d = mem[j+7]; + d = mem[j+8]; d = mem[j+9]; d = mem[j+10]; d = mem[j+11]; + d = mem[j+12]; d = mem[j+13]; d = mem[j+14]; d = mem[j+15]; + } + times(&tms); + stop = tms.tms_utime; + fprintf(stderr, "%5.3f MB/s\n", + (double)(LOOPSIZE/MB)/(double)(stop-start)*(double)CLK_TCK); + } + exit(0); +} diff --git a/src/tests/kernel/benchmarks/syscallbench.c b/src/tests/kernel/benchmarks/syscallbench.c new file mode 100644 index 0000000000..79f295efc3 --- /dev/null +++ b/src/tests/kernel/benchmarks/syscallbench.c @@ -0,0 +1,51 @@ +/* + * from ftp://ftp.netbsd.org/pub/NetBSD/misc/gmcgarry/bench/syscallbench.tar.gz + * + * gcc -Wall -Werror -O3 -static -o ctx ctx.c + */ + +#include +#include +#include +#include + +#define ITERATIONS 1000000 + +static void +usage(void) +{ + printf("syscallbench [-h]\n"); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + struct timeval before, after; + unsigned long overhead, elapsed; + int i; + pid_t pid; + + if (argc > 1) + usage(); + + gettimeofday(&before, NULL); + for (i=0; i