summaryrefslogtreecommitdiff
path: root/bench/runbench.myr
blob: 74ddfa56c40f408926363e49d4d617a36f63c1ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
use std

const Nsamp = 10

const main = {args : byte[:][:]
	var tot : flt64

	std.put("Running benchmarks: {} samples per binary\n", Nsamp);
	tot = 0.0;
	for arg in args
		tot = tot + timeit(arg)
	;;
	std.put("total:\t{}s\n", tot);
}


generic perror = {a : @a::(numeric,integral), msg : byte[:] -> @a
	if a < 0
		std.fatal("{}", msg)
	else
		-> a
	;;
}

const timeit = {prog -> flt64
	var avg, m, d, x, n : flt64

	avg = 0.0;
	m = 0.0;
	n = 0.0;
	for var i = 0; i < Nsamp; i++
		n = n + 1.0;
		x = run(prog);
		d = (x - avg);
		avg = avg + d/n;
		m = m + d*(x - avg);
	;;
	std.put("{}:\t{}s (σ^2: {})\n", prog, avg, m/(n-1.0));
	-> avg;
}

const run = {prog -> flt64
	var infd, outfd
	var pid
	var tm

	tm = std.now()
	pid = std.fork();
	if pid < 0
		std.fatal("Could not fork\n");
	elif pid == 0
		infd = perror(std.open("/dev/zero", std.Ordonly), "could not open /dev/zero")
		outfd = perror(std.open("/dev/null", std.Owronly), "could not open /dev/null")
		perror(std.dup2(infd, 0), "could not redirect stdin")
		perror(std.dup2(outfd, 1), "could not redirect stdout")
		std.execv(prog, [prog][:])
		std.fatal("Failed to exec\n")
	else
		match std.wait(pid)
		| `std.Wfailure:	std.fatal("could not wait\n")
		| `std.Waiterror:	std.fatal("running benchmark failed\n")
		| `std.Wsignalled:	std.fatal("running benchmark failed\n")
		| `std.Wsuccess:	/* nothing */
		;;
	;;
	-> (std.now() - tm castto(flt64)) / 1_000_000.0
}