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
--
⑨