ref: b154a740d6fab72c14c7fd2511e7071d31a9b6e7
parent: d818e0fc9c7b36b6cc1494bb2253792ea2c35f4b
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Jul 13 13:44:52 EDT 2025
all: break into separate binaries
--- a/bench.c
+++ b/bench.c
@@ -6,7 +6,7 @@
#define Nsec 1000000000ULL
#define BENCHTIME (Nsec) /* 1s in ns */
-uvlong boverhead;
+int NPROC;
/*
* nsec() is wallclock and can be adjusted by timesync
@@ -76,7 +76,11 @@
// stop
cycles(&b->ecycles);
b->ns += nanosec() - b->start;
- b->bcycles += b->ecycles - b->scycles - boverhead;
+ if(b->overheadns != -1)
+ b->ns -= b->overheadns;
+ b->bcycles += b->ecycles - b->scycles;
+ if(b->overheadcy != -1)
+ b->bcycles -= b->overheadcy;
}
static vlong
@@ -143,12 +147,16 @@
vlong d;
BResult res;
- n = 1;
+ b->overheadns = -1;
+ b->overheadcy = -1;
+ benchrunn(b, 0);
+ benchrunn(b, 0);
+ b->overheadns = b->ns;
+ b->overheadcy = b->bcycles;
+ n = 1;
benchrunn(b, n);
-
d = BENCHTIME;
-
while(b->ns < d && n < 1000000000) {
last = n;
if(nsperop(b) == 0) {
@@ -166,7 +174,7 @@
res.N = b->N;
res.ns = b->ns;
res.cycles = b->bcycles;
-
+ res.overhead = b->overheadns;
return res;
}
@@ -213,26 +221,20 @@
// setup. currently only calculates cycles() overhead.
// not strictly necessary, but will give better cycle counts.
void
-benchinit(void)
+benchinit(int, char **)
{
- int at;
- uvlong a, b;
+ char *e;
- /* figure out cycles overhead */
- boverhead = -1;
-
- for(at = 0; at < 1000000; at++) {
- cycles(&a);
- cycles(&b);
- if(boverhead > b - a)
- boverhead = b - a;
- }
-
+ if((e = getenv("NPROC")) == nil)
+ NPROC = 1;
+ else
+ NPROC = atoi(e);
+ free(e);
}
// bench a single function
void
-bench(char *name, BFn fn)
+bench(char *name, void (*fn)(B*))
{
B b;
BResult res;
@@ -249,6 +251,13 @@
res = benchrun(&b);
benchres(&res);
+}
+
+void
+xbench(char *name, void (*fn)(B*), void (*init)(void))
+{
+ init();
+ bench(name, fn);
}
// bench an array of functions
--- a/bench.h
+++ b/bench.h
@@ -1,15 +1,12 @@
-
typedef struct BItem BItem;
typedef struct BResult BResult;
typedef struct B B;
-typedef void (*BFn)(B* b);
-
// single benchmark function
struct BItem
{
char *name;
- BFn fn;
+ void (*fn)(B*);
};
// result of benchmarking
@@ -18,6 +15,7 @@
int N;
vlong ns;
uvlong cycles;
+ vlong overhead;
};
// type passed to bench functions
@@ -29,12 +27,18 @@
uvlong scycles; /* start cycles */
uvlong ecycles; /* end cycles */
uvlong bcycles; /* best cycles */
+ vlong overheadns; /* cost of doing 0 iters */
+ vlong overheadcy; /* cost of doing 0 iters, cycles */
BItem item;
};
extern int NPROC;
+#define BM(func) bench("func", func)
+#define XBM(func, init) xbench("func", func, init)
+
// public api
-void benchinit(void);
-void bench(char *name, BFn);
+void benchinit(int, char**);
+void bench(char *name, void (*)(B*));
+void xbench(char *name, void(*)(B*), void (*)(void));
void benchitems(BItem[], int);
--- a/fcall.c
+++ b/fcall.c
@@ -2,7 +2,6 @@
#include <libc.h>
#include "bench.h"
-#include "fns.h"
void
f0(void)
@@ -15,6 +14,11 @@
}
void
+f4(int, int, int, int)
+{
+}
+
+void
f16(int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int)
{
}
@@ -33,10 +37,33 @@
for(i = 0; i < b->N; i++)
f1(i);
}
+
void
+fcall4(B *b)
+{
+ int i;
+ for(i = 0; i < b->N; i++)
+ f4(i, i, i, i);
+}
+
+void
fcall16(B *b)
{
int i;
for(i = 0; i < b->N; i++)
f16(i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i);
-}
\ No newline at end of file
+}
+
+void
+main(int argc, char **argv)
+{
+ benchinit(argc, argv);
+
+ print("== function call overhead ==\n");
+ BM(fcall0);
+ BM(fcall1);
+ BM(fcall4);
+ BM(fcall16);
+ exits(nil);
+}
+
--- a/fns.h
+++ /dev/null
@@ -1,73 +1,0 @@
-
-#define BMARKS \
- \
- H("== fork/exec ==\n")\
- BM(benchfork1)\
- BM(benchrforkm1)\
- BM(benchexec1)\
- BM(benchexecm1)\
- BM(benchforkN)\
- BM(benchrforkmN)\
- BM(benchexecN)\
- BM(benchexecmN)\
- \
- H("== nop io ==\n") \
- BM(benchsysr1)\
- BM(benchreadzero)\
- BM(benchwritenull)\
- BM(benchreadmordor)\
- BM(benchwritemordor)\
- \
- H("== pipe io ==\n") \
- BM(benchpipe1)\
- BM(benchpipe16)\
- BM(benchpipe256)\
- BM(benchpipe4096)\
- BM(benchpipe4097)\
- BM(benchpipe32768)\
- \
- H("== locking (fast work) ==\n") \
- BM(benchlock1)\
- BM(benchqlock1)\
- BM(benchslock1)\
- BM(benchlock4)\
- BM(benchqlock4)\
- BM(benchslock4)\
- BM(benchlock16)\
- BM(benchqlock16)\
- BM(benchslock16)\
- BM(benchlock64)\
- BM(benchqlock64)\
- BM(benchslock64)\
- BM(benchlock512)\
- BM(benchqlock512)\
- BM(benchslock512)\
- \
- H("== locking (slow work) ==\n") \
- BM(benchlock1_w)\
- BM(benchqlock1_w)\
- BM(benchslock1_w)\
- BM(benchlock4_w)\
- BM(benchqlock4_w)\
- BM(benchslock4_w)\
- BM(benchlock16_w)\
- BM(benchqlock16_w)\
- BM(benchslock16_w)\
- BM(benchlock64_w)\
- BM(benchqlock64_w)\
- BM(benchslock64_w)\
- BM(benchlock512_w)\
- BM(benchqlock512_w)\
- BM(benchslock512_w)\
- \
- H("== function call overhead ==\n") \
- BM(fcall0)\
- BM(fcall1)\
- BM(fcall16)\
-
-#define H(x)
-#define BM(n) void n(B *b);
-BMARKS
-#undef BM
-#undef H
-
--- a/lock.c
+++ b/lock.c
@@ -2,7 +2,6 @@
#include <libc.h>
#include "bench.h"
-#include "fns.h"
#define NLockIters 1
@@ -145,3 +144,45 @@
void benchlock512_w(B *b) { lockbench(dolock, 512, work, b->N); }
void benchqlock512_w(B *b) { lockbench(doqlock, 512, work, b->N); }
void benchslock512_w(B *b) { lockbench(doslock, 512, work, b->N); }
+
+void
+main(int argc, char **argv)
+{
+ benchinit(argc, argv);
+
+ print("== locking (fast work) ==\n");
+ BM(benchlock1);
+ BM(benchqlock1);
+ BM(benchslock1);
+ BM(benchlock4);
+ BM(benchqlock4);
+ BM(benchslock4);
+ BM(benchlock16);
+ BM(benchqlock16);
+ BM(benchslock16);
+ BM(benchlock64);
+ BM(benchqlock64);
+ BM(benchslock64);
+ BM(benchlock512);
+ BM(benchqlock512);
+ BM(benchslock512);
+
+ print("== locking (slow work) ==\n");
+ BM(benchlock1_w);
+ BM(benchqlock1_w);
+ BM(benchslock1_w);
+ BM(benchlock4_w);
+ BM(benchqlock4_w);
+ BM(benchslock4_w);
+ BM(benchlock16_w);
+ BM(benchqlock16_w);
+ BM(benchslock16_w);
+ BM(benchlock64_w);
+ BM(benchqlock64_w);
+ BM(benchslock64_w);
+ BM(benchlock512_w);
+ BM(benchqlock512_w);
+ BM(benchslock512_w);
+ exits(nil);
+}
+
--- a/main.c
+++ /dev/null
@@ -1,30 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <regexp.h>
-#include "bench.h"
-#include "fns.h"
-
-int NPROC;
-
-
-void
-main(void)
-{
- char *e;
-
- if((e = getenv("NPROC")) == nil)
- NPROC = 1;
- else
- NPROC = atoi(e);
- free(e);
-
-
-
-#define S(n) n();
-#define H(x) print(x);
-#define BM(n) bench("n", n);
- BMARKS
-#undef BM
-#undef H
- exits(nil);
-}
--- a/mkfile
+++ b/mkfile
@@ -1,24 +1,26 @@
</$objtype/mkfile
-TARG=bench
+TARG=\
+ rdwr\
+ lock\
+ spawn\
+ fcall\
+
OFILES=\
- main.$O\
bench.$O\
- \
- rdwr.$O\
- lock.$O\
- spawn.$O\
- fcall.$O\
HFILES=\
bench.h\
- fns.h
bench:V: all $O.nop
- $O.out
+ for(t in $TARG)
+ $O.$t
-</sys/src/cmd/mkone
+bench.%:V: $O.%
+ $O.$stem
+
+</sys/src/cmd/mkmany
nop.$O: nop.c
$CC $CFLAGS nop.c
--- a/rdwr.c
+++ b/rdwr.c
@@ -2,7 +2,6 @@
#include <libc.h>
#include "bench.h"
-#include "fns.h"
void
benchsysr1(B *b)
@@ -67,8 +66,7 @@
close(pfd[1]);
break;
}
-}
-
+}
void benchreadzero(B *b) { benchread(b, "/dev/zero", 4); }
void benchwritenull(B *b) { benchwrite(b, "/dev/null", 4); }
@@ -80,3 +78,26 @@
void benchpipe4096(B *b) { benchpipe(b, 4096); }
void benchpipe4097(B *b) { benchpipe(b, 4097); }
void benchpipe32768(B *b) { benchpipe(b, 32768); }
+
+void
+main(int argc, char **argv)
+{
+ benchinit(argc, argv);
+
+ print("== nop io ==\n");
+ BM(benchsysr1);
+ BM(benchreadzero);
+ BM(benchwritenull);
+ BM(benchreadmordor);
+ BM(benchwritemordor);
+
+ print("== pipe io ==\n");
+ BM(benchpipe1);
+ BM(benchpipe16);
+ BM(benchpipe256);
+ BM(benchpipe4096);
+ BM(benchpipe4097);
+ BM(benchpipe32768);
+ exits(nil);
+}
+
--- a/spawn.c
+++ b/spawn.c
@@ -2,7 +2,6 @@
#include <libc.h>
#include "bench.h"
-#include "fns.h"
#define DirtySz 1024*1024*1024
void *junk;
@@ -29,7 +28,6 @@
if(r == -1)
sysfatal("rfork: %r");
if(r == 0){
- sleep(1000);
fn(n/NPROC);
exits(nil);
}
@@ -147,3 +145,23 @@
{
doit(benchexecm, b->N);
}
+
+void
+main(int argc, char **argv)
+{
+ benchinit(argc, argv);
+
+ print("== fork/exec (single spawner) ==\n");
+ BM(benchfork1);
+ BM(benchrforkm1);
+ BM(benchexec1);
+ BM(benchexecm1);
+
+ print("== fork/exec (%d spawners) ==\n", NPROC);
+ BM(benchforkN);
+ BM(benchrforkmN);
+ BM(benchexecN);
+ BM(benchexecmN);
+ exits(nil);
+}
+
--
⑨