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
This commit is contained in:
Jérôme Duval 2005-01-07 15:28:48 +00:00
parent 36351e2d44
commit 34720c47f1
7 changed files with 491 additions and 0 deletions

View File

@ -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 ;

View File

@ -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
;

View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/time.h>
#include <signal.h>
#if defined (LWP)
#include <sys/ucontext.h>
#include <sys/lwp.h>
#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<ITERATIONS; i++) {
if (elapsed_times[i] < min_time)
min_time = elapsed_times[i];
if (elapsed_times[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<ITERATIONS; count++) {
gettimeofday(&before, NULL);
for (i=0; i<PASSES/2; i++) {
ch = 0;
if (write(fd0[1], &ch, 1) != 1)
errx(1, "parent write failed");
if (read(fd1[0], &ch, 1) != 1)
errx(1, "parent read failed");
}
gettimeofday(&after, NULL);
elapsed = 1000000 * (after.tv_sec - before.tv_sec);
elapsed += after.tv_usec - before.tv_usec;
elapsed_times[count] = elapsed;
}
if (!use_lwps)
kill(childpid, SIGTERM);
dump_results();
return (0);
}
/*
* PMAX_SA:
*
* min latency: 93.100000
* max latency: 150.700000
* mean latency: 100.857581
*
* PMAX_CHOOSEPROC:
*
* min latency: 49.350000
* max latency: 76.750000
* mean latency: 54.141626
*
* PMAX_OLD:
*
* min latency: 54.750000
* max latency: 76.050000
* mean latency: 60.088654
*
* HP300_SA:
*
* min latency: 352.560000
* max latency: 402.960000
* mean latency: 367.836250
*
* HP300_CHOOSEPROC:
*
* min latency: 129.200000
* max latency: 187.040000
* mean latency: 142.528223
*
* HP300_OLD:
*
* min latency: 357.360000
* max latency: 414.400000
* mean latency: 372.436104
*
*/

View File

@ -0,0 +1,52 @@
/*
* from ftp://ftp.netbsd.org/pub/NetBSD/misc/gmcgarry/bench/execbench.tar.gz
*/
#define errx(x,y...) { fprintf(stderr, y); fprintf(stderr, "\n"); exit(x); }
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
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);
}

View File

@ -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 <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/wait.h>
/*
* 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<nforks; i++) {
child = fork();
if (child == -1) {
perror("fork");
exit(-1);
}
if (child == 0)
_exit(-1);
while ((pid = wait(&status)) != -1 && pid != child)
;
}
gettimeofday(&after, NULL);
elapsed = 1000000 * (after.tv_sec - before.tv_sec);
elapsed += (after.tv_usec - before.tv_usec);
printf ("Time: %d microseconds.\n", elapsed/nforks);
exit(0);
}

View File

@ -0,0 +1,83 @@
/*
* from ftp://ftp.netbsd.org/pub/NetBSD/misc/gmcgarry/bench/memspeed.c
*
* Compilation:
*
* gcc -O3 -fomit-frame-pointer memspeed.c -o memspeed
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/times.h>
#include <time.h>
#include <sys/types.h>
#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);
}

View File

@ -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 <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#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<ITERATIONS; i++) {
}
gettimeofday(&after, NULL);
overhead = 1000000 * (after.tv_sec - before.tv_sec);
overhead += after.tv_usec - before.tv_usec;
gettimeofday(&before, NULL);
for (i=0; i<ITERATIONS; i++) {
pid = getpid();
}
gettimeofday(&after, NULL);
elapsed = 1000000 * (after.tv_sec - before.tv_sec);
elapsed += after.tv_usec - before.tv_usec;
printf("syscall time: %ld microseconds\n",
(1000*(elapsed-overhead))/ITERATIONS);
return (0);
}