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:
parent
36351e2d44
commit
34720c47f1
@ -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 ;
|
||||
|
22
src/tests/kernel/benchmarks/Jamfile
Normal file
22
src/tests/kernel/benchmarks/Jamfile
Normal 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
|
||||
;
|
||||
|
212
src/tests/kernel/benchmarks/ctxbench.c
Normal file
212
src/tests/kernel/benchmarks/ctxbench.c
Normal 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
|
||||
*
|
||||
*/
|
52
src/tests/kernel/benchmarks/execbench.c
Normal file
52
src/tests/kernel/benchmarks/execbench.c
Normal 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);
|
||||
}
|
70
src/tests/kernel/benchmarks/forkbench.c
Normal file
70
src/tests/kernel/benchmarks/forkbench.c
Normal 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);
|
||||
}
|
83
src/tests/kernel/benchmarks/memspeed.c
Normal file
83
src/tests/kernel/benchmarks/memspeed.c
Normal 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);
|
||||
}
|
51
src/tests/kernel/benchmarks/syscallbench.c
Normal file
51
src/tests/kernel/benchmarks/syscallbench.c
Normal 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user