shithub: gefs

Download patch

ref: bb7420d7d8bd0abd589481ae05c6e0ae95995e2d
parent: 3025f32d5e945686d766185f94d1792225ee39b4
author: Ori Bernstein <ori@eigenstate.org>
date: Wed Apr 19 23:47:38 EDT 2023

fsbench: add current benchmark suite

--- a/main.c
+++ b/main.c
@@ -145,7 +145,7 @@
 		break;
 	case 'r':
 		ream = 1;
-		reamuser = ARGF();
+		reamuser = EARGF(usage());
 		break;
 	case 'g':
 		grow = 1;
--- /dev/null
+++ b/test/fsbench.c
@@ -1,0 +1,452 @@
+#include <u.h>
+#include <libc.h>
+#include <libsec.h>
+#include <thread.h>
+
+int mainstacksize = 2*1024*1024;
+typedef struct Bench Bench;
+
+enum {
+	KiB	= 1024ULL,
+	MiB	= 1024ULL*KiB,
+	GiB	= 1024ULL*MiB,
+	Bufsz	= IOUNIT,
+};
+
+enum {
+	Bps,
+	Fps,
+};
+	
+struct Bench {
+	char	*name;
+	char	*unit;
+	vlong	(*fn)(Bench*);
+	vlong	reps;
+	int	nproc;
+	int	id;
+	Channel	*rc;
+
+	vlong	i0;
+	vlong	i1;
+	vlong	i2;
+	char	*s0;
+	char	*s1;
+};
+
+#define	GBIT64(p)	((u32int)(((uchar*)(p))[0]|(((uchar*)(p))[1]<<8)|\
+				(((uchar*)(p))[2]<<16)|(((uchar*)(p))[3]<<24)) |\
+			((uvlong)(((uchar*)(p))[4]|(((uchar*)(p))[5]<<8)|\
+				(((uchar*)(p))[6]<<16)|(((uchar*)(p))[7]<<24)) << 32))
+vlong
+vrand(vlong n)
+{
+	uchar buf[8];
+	vlong slop, v;
+
+	slop = 0x7fffffffffffffffULL % n;
+	do{
+		prng(buf, 8);
+		v = GBIT64(buf);
+	}while(v <= slop);
+	return v % n;
+}
+
+vlong
+wrfile_la(Bench *b)
+{
+	char buf[Bufsz];
+	vlong i;
+	int fd;
+
+	if((fd = create(b->s0, OWRITE, 0666)) == -1)
+		sysfatal("open: %r");
+	for(i = 0; i < b->i0; i += Bufsz)
+		if(write(fd, buf, Bufsz) != Bufsz)
+			sysfatal("write: %r");
+	close(fd);
+	return b->i0/MiB;
+}
+
+vlong
+wrfile_ra(Bench *b)
+{
+	char buf[Bufsz];
+	vlong i, n, j, t, *off;
+	int fd;
+
+	n = b->i0/Bufsz;
+	if((fd = create(b->s0, OWRITE, 0666)) == -1)
+		sysfatal("open: %r");
+	if((off = malloc(n*sizeof(vlong))) == nil)
+		sysfatal("malloc: %r");
+	for(i = 0; i < n; i++)
+		off[i] = i*Bufsz;
+	for (i = n - 1; i > 0; i--) {
+		j = vrand(i+1);
+		t = off[i];
+		off[i] = off[j];
+		off[j] = t;
+	}
+	for(i = 0; i < n; i++)
+		if(pwrite(fd, buf, Bufsz, off[i]) != Bufsz)
+			sysfatal("write: %r");
+	close(fd);
+	free(off);
+	return b->i0/MiB;
+}
+
+vlong
+wrfile_rr(Bench *b)
+{
+	char buf[Bufsz];
+	vlong i, n, j, t, *off;
+	int fd;
+
+	n = b->i0/Bufsz;
+	if((fd = create(b->s0, OWRITE, 0666)) == -1)
+		sysfatal("open: %r");
+	if((off = malloc(n*sizeof(vlong))) == nil)
+		sysfatal("malloc: %r");
+	for(i = 0; i < n; i++)
+		off[i] = i*Bufsz;
+	for (i = n - 1; i > 0; i--) {
+		j = vrand(i+1);
+		t = off[i];
+		off[i] = off[j];
+		off[j] = t;
+	}
+	for(i = 0; i < n; i++)
+		if(pwrite(fd, buf, Bufsz, off[i] + vrand(100)) != Bufsz)
+			sysfatal("write: %r");
+	close(fd);
+	free(off);
+	return b->i0/MiB;
+}
+
+vlong
+rdfile_la(Bench *b)
+{
+	char buf[Bufsz];
+	vlong i, rep;
+	int fd;
+
+	if((fd = open(b->s0, OREAD)) == -1)
+		sysfatal("open: %r");
+	for(rep = 0; rep < b->reps; rep++){
+		seek(fd, 0, 0);
+		for(i = 0; i < b->i0; i += Bufsz)
+			if(read(fd, buf, Bufsz) != Bufsz)
+				sysfatal("write: %r");
+	}
+	close(fd);
+	return b->reps*(b->i0/MiB);
+}
+vlong
+rdfile_ra(Bench *b)
+{
+	char buf[Bufsz];
+	vlong i, rep;
+	uvlong off;
+	int fd;
+
+	if((fd = open(b->s0, OREAD)) == -1)
+		sysfatal("open: %r");
+	for(rep = 0; rep < b->reps; rep++){
+		seek(fd, 0, 0);
+		for(i = 0; i < b->i0; i += Bufsz){
+			off = vrand(b->i0-Bufsz) & ~(Bufsz-1);
+			if(pread(fd, buf, Bufsz, off) != Bufsz)
+				sysfatal("write: %r");
+		}
+	}
+	close(fd);
+	return b->reps*(b->i0/MiB);
+}
+
+vlong
+rwfile_lala(Bench *b)
+{
+	char buf[64];
+	Bench bb;
+	vlong r;
+
+	bb = *b;
+	if(b->id >= b->i1)
+		return rdfile_la(&bb);
+	else{
+		snprint(buf, sizeof(buf), "%s%d.w%d", b->s0, getpid(), b->id);
+		bb.s0 = buf;
+		return wrfile_la(&bb);
+	}
+}
+
+vlong
+rdfile_rr(Bench *b)
+{
+	char buf[Bufsz];
+	vlong i, rep;
+	uvlong off;
+	int fd;
+
+	if((fd = open(b->s0, OREAD)) == -1)
+		sysfatal("open: %r");
+	for(rep = 0; rep < b->reps; rep++){
+		for(i = 0; i < b->i0; i += Bufsz){
+			off = vrand(b->i0-Bufsz);
+			if(pread(fd, buf, Bufsz, off) != Bufsz)
+				sysfatal("read: %r");
+		}
+	}
+	close(fd);
+	return b->reps*(b->i0/MiB);
+}
+
+vlong
+createflat(Bench *b)
+{
+	char buf[Bufsz];
+	int i, fd;
+
+	for(i = 0; i < b->i0; i++){
+		snprint(buf, sizeof(buf), "%s%d", b->s0, i);
+		if((fd = create(buf, OWRITE, 0666)) == -1)
+			sysfatal("create: %r");
+		if(b->i1 != 0)
+			write(fd, buf, b->i1);
+		close(fd);
+	}
+	return b->i0;
+}
+
+int
+createlevel(int n, int d)
+{
+	char buf[Bufsz];
+	int i, s, fd;
+
+	s = 0;
+	for(i = 0; i < n; i++){
+		snprint(buf, sizeof(buf), "%d", i);
+		if(d > 0){
+			if((fd = create(buf, OWRITE, 0777|DMDIR)) == -1)
+				sysfatal("create: %r");
+			if(chdir(buf) == -1)
+				sysfatal("chdir %s: %r", buf);
+			s += createlevel(n, d-1);
+			chdir("..");
+		}else{
+			if((fd = create(buf, OWRITE, 0666)) == -1)
+				sysfatal("create: %r");
+			s++;
+		}
+		close(fd);
+	}
+	return s;
+}
+
+vlong
+createhier(Bench *b)
+{
+	return createlevel(b->i0, b->i1);
+}
+
+vlong
+listfiles(Bench *b)
+{
+	char buf[Bufsz];
+	int i, r, fd;
+
+	for(i = 0; i < b->reps; i++){
+		if((fd = open(".", OREAD)) == -1)
+			sysfatal("open .: %r");
+		while(1){
+			if((r = read(fd, buf, sizeof(buf))) == -1)
+				sysfatal("read: %r");
+			if(r == 0)
+				break;
+		}
+		close(fd);
+	}
+	return b->reps*b->i0;
+}
+
+vlong
+randopen(Bench *b)
+{
+	char buf[Bufsz];
+	int i, fd;
+
+	for(i = 0; i < b->reps; i++){
+		snprint(buf, sizeof(buf), "%s%d", b->s0, vrand(b->i0));
+		if((fd = open(buf, OREAD)) == -1)
+			sysfatal("open: %r");
+		if(b->i0)
+			if(read(fd, buf, sizeof(buf)) == -1)
+				sysfatal("read: %r");
+		close(fd);	
+	}
+	return b->reps;
+}
+
+void
+launch(void *p)
+{
+	Bench *b;
+	vlong r;
+
+	b = p;
+	r = b->fn(b);
+	send(b->rc, &r);
+}
+
+vlong
+runpar(Bench *b)
+{
+	vlong r, sum;
+	Bench *sub;
+	int i;
+	
+	sum = 0;
+	b->rc = chancreate(sizeof(vlong), b->nproc);
+	if((sub = calloc(b->nproc, sizeof(Bench))) == nil)
+		sysfatal("malloc: %r");
+	for(i = 0; i < b->nproc; i++){
+		sub[i] = *b;
+		sub[i].id = i;
+		proccreate(launch, &sub[i], mainstacksize);
+	}
+	for(i = 0; i < b->nproc; i++){
+		recv(b->rc, &r);
+		sum += r;
+	}
+	free(sub);
+	return sum;
+}
+
+void
+runbench(Bench *b, int nb)
+{
+	char *unit[] = {"ns", "us", "ms", "s"};
+	double oc, dt;
+	vlong t0, t1;
+	int i, j;
+
+	for(i = 0; i < nb; i++){
+		if(b[i].reps == 0)
+			b[i].reps = 1;
+		print("%20s:\t", b[i].name);
+		t0 = nsec();
+		if(b[i].nproc <= 1){
+			b[i].id = -1;
+			oc = b[i].fn(&b[i]);
+		}else
+			oc = runpar(&b[i]);
+		t1 = nsec();
+		dt = (t1 - t0);
+		for(j = 0; j < nelem(unit)-1; j++)
+			if(dt/100 < 1)
+				break;
+			else
+				dt /= 1000.0;
+		print("%f%s (%f %s/%s)\n", dt, unit[j], (double)oc/dt, b[i].unit, unit[j]);
+	}
+}
+
+void
+threadmain(int argc, char **argv)
+{
+	Bench marks[] = {
+		/* l => linear, a => aligned, r => random */
+		{.name="wrcached_la",	.i0=256*MiB,	.reps=1, .unit="MiB", .fn=wrfile_la, .s0="cached0"},
+		{.name="rdcached_lala",	.i0=256*MiB,	.reps=2, .unit="MiB", .fn=rdfile_la, .s0="cached0"},
+		{.name="rdcached_lara",	.i0=256*MiB,	.reps=2, .unit="MiB", .fn=rdfile_ra, .s0="cached0"},
+		{.name="rdcached_larr",	.i0=256*MiB,	.reps=2, .unit="MiB", .fn=rdfile_rr, .s0="cached0"},
+
+		{.name="rdcached_lala_2p",	.i0=256*MiB,	.reps=2, .unit="MiB", .fn=rdfile_la, .s0="cached0", .nproc=2},
+		{.name="rdcached_lara_2p",	.i0=256*MiB,	.reps=2, .unit="MiB", .fn=rdfile_ra, .s0="cached0", .nproc=2},
+		{.name="rdcached_larr_2p",	.i0=256*MiB,	.reps=2, .unit="MiB", .fn=rdfile_rr, .s0="cached0", .nproc=2},
+
+		{.name="rdcached_lala_4p",	.i0=256*MiB,	.reps=2, .unit="MiB", .fn=rdfile_la, .s0="cached0", .nproc=4},
+		{.name="rdcached_lara_4p",	.i0=256*MiB,	.reps=2, .unit="MiB", .fn=rdfile_ra, .s0="cached0", .nproc=4},
+		{.name="rdcached_larr_4p",	.i0=256*MiB,	.reps=2, .unit="MiB", .fn=rdfile_rr, .s0="cached0", .nproc=4},
+
+		{.name="rdcached_lala_8p",	.i0=256*MiB,	.reps=2, .unit="MiB", .fn=rdfile_la, .s0="cached0", .nproc=8},
+		{.name="rdcached_lara_8p",	.i0=256*MiB,	.reps=2, .unit="MiB", .fn=rdfile_ra, .s0="cached0", .nproc=8},
+		{.name="rdcached_larr_8p",	.i0=256*MiB,	.reps=2, .unit="MiB", .fn=rdfile_rr, .s0="cached0", .nproc=8},
+
+		{.name="wrcached_ra",	.i0=256*MiB,	.reps=1, .unit="MiB", .fn=wrfile_ra, .s0="cached1"},
+		{.name="rdcached_rala",	.i0=256*MiB,	.reps=10, .unit="MiB", .fn=rdfile_la, .s0="cached1"},
+		{.name="rdcached_rara",	.i0=256*MiB,	.reps=10, .unit="MiB", .fn=rdfile_ra, .s0="cached1"},
+		{.name="rdcached_rarr",	.i0=256*MiB,	.reps=10, .unit="MiB", .fn=rdfile_rr, .s0="cached1"},
+
+		{.name="wrcached_rr",	.i0=256*MiB,	.reps=1, .unit="MiB", .fn=wrfile_rr, .s0="cached2"},
+		{.name="rdcached_rrla",	.i0=256*MiB,	.reps=10, .unit="MiB", .fn=rdfile_la, .s0="cached2"},
+		{.name="rdcached_rrra",	.i0=256*MiB,	.reps=10, .unit="MiB", .fn=rdfile_ra, .s0="cached2"},
+		{.name="rdcached_rrrr",	.i0=256*MiB,	.reps=10, .unit="MiB", .fn=rdfile_rr, .s0="cached2"},
+
+		{.name="rwcached_la_r0_w2_w",	.i0=64*MiB,	.reps=10, .unit="MiB", .fn=rwfile_lala, .s0="cached0", .nproc=2, .i1=2},
+		{.name="rwcached_la_r0_w4_w",	.i0=64*MiB,	.reps=10, .unit="MiB", .fn=rwfile_lala, .s0="cached0", .nproc=4, .i1=4},
+		{.name="rwcached_la_r1_w1_w",	.i0=64*MiB,	.reps=10, .unit="MiB", .fn=rwfile_lala, .s0="cached0", .nproc=2, .i1=1},
+		{.name="rwcached_la_r3_w1_w",	.i0=64*MiB,	.reps=10, .unit="MiB", .fn=rwfile_lala, .s0="cached0", .nproc=4, .i1=1},
+		{.name="rwcached_la_r2_w2_w",	.i0=64*MiB,	.reps=10, .unit="MiB", .fn=rwfile_lala, .s0="cached0", .nproc=4, .i1=2},
+		{.name="rwcached_la_r6_w2_w",	.i0=64*MiB,	.reps=10, .unit="MiB", .fn=rwfile_lala, .s0="cached0", .nproc=8, .i1=2},
+		{.name="rwcached_la_r4_w4_w",	.i0=64*MiB,	.reps=10, .unit="MiB", .fn=rwfile_lala, .s0="cached0", .nproc=8, .i1=4},
+
+		{.name="rwcached_la_r1_w1_r",	.i0=64*MiB,	.reps=10, .unit="MiB", .fn=rwfile_lala, .s0="cached0", .nproc=2, .i1=1},
+		{.name="rwcached_la_r2_w1_r",	.i0=64*MiB,	.reps=10, .unit="MiB", .fn=rwfile_lala, .s0="cached0", .nproc=3, .i1=1},
+		{.name="rwcached_la_r3_w1_r",	.i0=64*MiB,	.reps=10, .unit="MiB", .fn=rwfile_lala, .s0="cached0", .nproc=4, .i1=1},
+		{.name="rwcached_la_r1_w2_r",	.i0=64*MiB,	.reps=10, .unit="MiB", .fn=rwfile_lala, .s0="cached0", .nproc=4, .i1=2},
+		{.name="rwcached_la_r1_w2_r",	.i0=64*MiB,	.reps=10, .unit="MiB", .fn=rwfile_lala, .s0="cached0", .nproc=3, .i1=2},
+		{.name="rwcached_la_r2_w2_r",	.i0=64*MiB,	.reps=10, .unit="MiB", .fn=rwfile_lala, .s0="cached0", .nproc=4, .i1=2},
+		{.name="rwcached_la_r4_w2_r",	.i0=64*MiB,	.reps=10, .unit="MiB", .fn=rwfile_lala, .s0="cached0", .nproc=4, .i1=2},
+		{.name="rwcached_la_r6_w2_r",	.i0=64*MiB,	.reps=10, .unit="MiB", .fn=rwfile_lala, .s0="cached0", .nproc=8, .i1=2},
+		{.name="rwcached_la_r4_w4_r",	.i0=64*MiB,	.reps=10, .unit="MiB", .fn=rwfile_lala, .s0="cached0", .nproc=8, .i1=4},
+
+//		{.name="rwcached_lara",	.i0=512*MiB,	.reps=10, .unit="MiB", .fn=rwfile_la, .s0="cached0", .i0=1, .i1=3},
+//		{.name="rwcached_la",	.i0=512*MiB,	.reps=10, .unit="MiB", .fn=rwfile_la, .s0="cached0", .i0=3, .i1=3},
+//		{.name="rwcached_la",	.i0=512*MiB,	.reps=10, .unit="MiB", .fn=rwfile_la, .s0="cached0", .i0=10, .i1=10},
+
+
+		{.name="wrlarge_la",	.i0=16*GiB,	.reps=1, .unit="MiB", .fn=wrfile_la, .s0="large0"},
+		{.name="rdlarge_lala",	.i0=16*GiB,	.reps=1, .unit="MiB", .fn=rdfile_la, .s0="large0"},
+		{.name="rdlarge_lara",	.i0=16*GiB,	.reps=1, .unit="MiB", .fn=rdfile_ra, .s0="large0"},
+//		{.name="rdlarge_larr",	.i0=16*GiB,	.reps=1, .unit="MiB", .fn=rdfile_rr, .s0="large0"},
+
+		{.name="wrlarge_ra",	.i0=16*GiB,	.reps=1, .unit="MiB", .fn=wrfile_ra, .s0="large1"},
+		{.name="rdlarge_lara",	.i0=16*GiB,	.reps=1, .unit="MiB", .fn=rdfile_la, .s0="large1"},
+		{.name="rdlarge_rara",	.i0=16*GiB,	.reps=1, .unit="MiB", .fn=rdfile_ra, .s0="large1"},
+//		{.name="rdlarge_rarr",	.i0=16*GiB,	.reps=1, .unit="MiB", .fn=rdfile_rr, .s0="large1"},
+
+//		{.name="wrlarge_rr",	.i0=16*GiB,	.reps=1, .unit="MiB", .fn=wrfile_rr, .s0="large2"},
+//		{.name="rdlarge_larr",	.i0=16*GiB,	.reps=1, .unit="MiB", .fn=rdfile_la, .s0="large2"},
+//		{.name="rdlarge_rarr",	.i0=16*GiB,	.reps=1, .unit="MiB", .fn=rdfile_ra, .s0="large2"},
+//		{.name="rdlarge_rrrr",	.i0=16*GiB,	.reps=1, .unit="MiB", .fn=rdfile_rr, .s0="large2"},
+
+		{.name="createflat",	.i0=100*1000,	.reps=1, 	.unit="files", .fn=createflat, .s0="cz"},
+		{.name="write1flat",	.i0=100*1000,	.reps=1, 	.unit="files", .fn=createflat, .i1=1, .s0="c1"},
+		{.name="write100flat",	.i0=100*1000,	.reps=1, 	.unit="files", .fn=createflat, .i1=100, .s0="c100"},
+		{.name="write1027flat",	.i0=100*1000,	.reps=1, 	.unit="files", .fn=createflat, .i1=1027, .s0="c1027"},
+		{.name="listfflat",	.i0=100*1000,	.reps=10,	.unit="files", .fn=listfiles},
+		{.name="openfflat",	.i0=100*1000,	.reps=100*1000, .unit="files", .fn=randopen, .s0="cz"},
+		{.name="read0flat",	.i0=100*1000,	.reps=100*1000, .unit="files", .fn=randopen, .i1=1, .s0="cz"},
+		{.name="read1flat",	.i0=100*1000,	.reps=100*1000, .unit="files", .fn=randopen, .i1=1, .s0="c1"},
+		{.name="read100flat",	.i0=100*1000,	.reps=100*1000, .unit="files", .fn=randopen, .i1=1, .s0="c100"},
+		{.name="read1027flat",	.i0=100*1000,	.reps=100*1000, .unit="files", .fn=randopen, .i1=1, .s0="c1027"},
+
+//		{.name="createheir",	.i0=3, .i1=10,	.reps=1, .unit="files", .fn=createhier},
+//		{.name="openheir",	.i0=3, .i1=10,	.reps=1, .unit="files", .fn=randwalk},
+	};
+
+	ARGBEGIN{
+	}ARGEND;
+	
+	if(argc != 1){
+		fprint(2, "usage: %s wdir\n", argv0);
+		exits("usage");
+	}
+	if(chdir(argv[0]) == -1)
+		sysfatal("chdir: %r");
+	runbench(marks, nelem(marks));
+	exits(nil);
+}
--- a/test/mkgefs.rc
+++ b/test/mkgefs.rc
@@ -2,7 +2,7 @@
 
 @{cd .. && mk all}
 ../6.out -r $user -f $1
-../6.out -n gefs.test -A -m 1024 -f $1
+../6.out -n gefs.test -A -m 2048 -f $1
 
 mount -c /srv/gefs.test /n/gefs
 mount -c /srv/gefs.test /n/gefs.adm adm