Skip to content

Commit aeda82d

Browse files
committed
wip
1 parent 3fb48f5 commit aeda82d

21 files changed

Lines changed: 996 additions & 78 deletions

Makefile

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ LDLIBS+=-lm -lreadline vendor/utf8proc/libutf8proc.a
44
SANITIZERS+=address,undefined
55

66
ifeq ($(TARGET),release)
7-
CFLAGS+=-DNDEBUG -O3 -flto
7+
CFLAGS+=-DNDEBUG -O3 -flto -fomit-frame-pointer -fno-asynchronous-unwind-tables -march=native
88
else ifeq ($(TARGET),profile)
99
CFLAGS+=-DPROFILE -pg -O3 -flto --coverage
1010
endif
@@ -37,15 +37,17 @@ vendor/utf8proc/libutf8proc.a:
3737

3838
# Generate a release binary using profile-guided optimization
3939
profile-opt:
40-
CFLAGS='-fprofile-generate' $(MAKE) clean cbcvm TARGET=release
41-
./cbcvm bf.cb bench.b
42-
$(MAKE) clean
43-
CFLAGS='-fprofile-use -fprofile-correction' $(MAKE) TARGET=release
40+
CFLAGS='-fprofile-instr-generate' $(MAKE) clean cbcvm TARGET=release
41+
LLVM_PROFILE_FILE='default_%p_%m.profraw' ./cbcvm bench/bf.cb bench/bench.b
42+
llvm-profdata merge -o default.profdata default_*.profraw
43+
rm cbcvm
44+
CFLAGS='-fprofile-instr-use=default.profdata' $(MAKE) TARGET=release
4445
find . -name '*.gcda' -delete
46+
rm -f default_*.profraw default.profdata
4547

4648
clean:
4749
[ -f cbcvm ] && rm cbcvm || true
48-
-rm $(OBJ) $(DEP)
50+
-rm -f $(OBJ) $(DEP)
4951
find . \( -name '*.gcda' -o -name '*.gcno' -o -name 'gmon.out' \) -delete
5052
$(MAKE) -C vendor/utf8proc clean
5153

bench/bf-fast.cb

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import array;
2+
import arraylist;
3+
import fs;
4+
import iter;
5+
import string;
6+
7+
struct Tape {
8+
pos,
9+
data,
10+
}
11+
12+
function tape_new() {
13+
return Tape {
14+
pos = 0,
15+
data = arraylist::from_array(1, [0]),
16+
};
17+
}
18+
19+
struct Op { type, value }
20+
21+
function parse(it) {
22+
let ops = arraylist::new();
23+
let c;
24+
25+
while ((c = iter::next(it)) != iter::STOP) {
26+
if (c == '+') {
27+
ops.push(Op{type="inc", value=1});
28+
} else if (c == '-') {
29+
ops.push(Op{type="inc", value=-1});
30+
} else if (c == '>') {
31+
ops.push(Op{type="move", value=1});
32+
} else if (c == '<') {
33+
ops.push(Op{type="move", value=-1});
34+
} else if (c == '.') {
35+
ops.push(Op{type="print"});
36+
} else if (c == '[') {
37+
ops.push(Op{type="loop", value=parse(it)});
38+
} else if (c == ']') {
39+
break;
40+
}
41+
}
42+
43+
return ops.to_array();
44+
}
45+
46+
function run(tape, ops) {
47+
let len = array::length(ops);
48+
49+
for (let i = 0; i < len; i += 1) {
50+
let op = ops[i];
51+
52+
if (op.type == "inc") {
53+
tape.data._array[tape.pos] += op.value;
54+
} else if (op.type == "move") {
55+
tape.pos += op.value;
56+
if (tape.pos >= tape.data._length) {
57+
tape.data.push(0);
58+
}
59+
} else if (op.type == "print") {
60+
print(chr(tape.data._array[tape.pos]));
61+
} else if (op.type == "loop") {
62+
while (tape.data._array[tape.pos] != 0) {
63+
run(tape, op.value);
64+
}
65+
}
66+
}
67+
}
68+
69+
let args = argv();
70+
if (array::length(args) != 1) {
71+
println("Usage: ./cbcvm bf.cb <program>");
72+
} else {
73+
let it = iter::iter(fs::read_file(args[0]));
74+
run(tape_new(), parse(it));
75+
}

bench/binary_trees.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import sys
2+
3+
4+
def make_tree(depth):
5+
if not depth:
6+
return None, None
7+
depth -= 1
8+
return make_tree(depth), make_tree(depth)
9+
10+
11+
def check_tree(node):
12+
(left, right) = node
13+
if not left:
14+
return 1
15+
return 1 + check_tree(left) + check_tree(right)
16+
17+
18+
min_depth = 4
19+
max_depth = max(min_depth + 2, int(sys.argv[1]))
20+
stretch_depth = max_depth + 1
21+
22+
print(
23+
"stretch tree of depth %d\t check:" % stretch_depth,
24+
check_tree(make_tree(stretch_depth)),
25+
)
26+
27+
long_lived_tree = make_tree(max_depth)
28+
29+
iterations = 2**max_depth
30+
31+
for depth in range(min_depth, stretch_depth, 2):
32+
check = 0
33+
for i in range(1, iterations + 1):
34+
check += check_tree(make_tree(depth))
35+
36+
print("%d\t trees of depth %d\t check:" % (iterations, depth), check)
37+
iterations //= 4
38+
39+
print("long lived tree of depth %d\t check:" % max_depth, check_tree(long_lived_tree))

bench/fasta.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# The Computer Language Benchmarks Game
2+
# https://salsa.debian.org/benchmarksgame-team/benchmarksgame/
3+
#
4+
# Naive transliteration from Drake Diedrich's C program
5+
# contributed by Isaac Gouy
6+
#
7+
8+
from sys import argv
9+
10+
IM = 139968
11+
IA = 3877
12+
IC = 29573
13+
SEED = 42
14+
15+
seed = SEED
16+
17+
18+
def fastaRand(max):
19+
global seed
20+
seed = (seed * IA + IC) % IM
21+
return max * seed / IM
22+
23+
24+
ALU = (
25+
"GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG"
26+
"GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA"
27+
"CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT"
28+
"ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA"
29+
"GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG"
30+
"AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC"
31+
"AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA"
32+
)
33+
34+
IUB = "acgtBDHKMNRSVWY"
35+
IUB_P = [
36+
0.27,
37+
0.12,
38+
0.12,
39+
0.27,
40+
0.02,
41+
0.02,
42+
0.02,
43+
0.02,
44+
0.02,
45+
0.02,
46+
0.02,
47+
0.02,
48+
0.02,
49+
0.02,
50+
0.02,
51+
]
52+
53+
HomoSapiens = "acgt"
54+
HomoSapiens_P = [0.3029549426680, 0.1979883004921, 0.1975473066391, 0.3015094502008]
55+
56+
LINELEN = 60
57+
58+
59+
# slowest character-at-a-time output
60+
def repeatFasta(seq, n):
61+
length = len(seq)
62+
i = 0
63+
# explicit line buffer
64+
b = ""
65+
for i in range(0, n):
66+
b += seq[i % length]
67+
if i % LINELEN == LINELEN - 1:
68+
print(b)
69+
b = ""
70+
if i % LINELEN != 0:
71+
print(b)
72+
73+
74+
def randomFasta(seq, probability, n):
75+
length = len(seq)
76+
i, j = 0, 0
77+
# explicit line buffer
78+
b = ""
79+
for i in range(0, n):
80+
v = fastaRand(1.0)
81+
# slowest idiomatic linear lookup. Fast if len is short though.
82+
for j in range(0, length):
83+
v -= probability[j]
84+
if v < 0:
85+
break
86+
b += seq[j]
87+
if i % LINELEN == LINELEN - 1:
88+
print(b)
89+
b = ""
90+
if (i + 1) % LINELEN != 0:
91+
print(b)
92+
93+
94+
def main(n):
95+
print(">ONE Homo sapiens alu")
96+
repeatFasta(ALU, n * 2)
97+
98+
print(">TWO IUB ambiguity codes")
99+
randomFasta(IUB, IUB_P, n * 3)
100+
101+
print(">THREE Homo sapiens frequency")
102+
randomFasta(HomoSapiens, HomoSapiens_P, n * 5)
103+
104+
105+
if __name__ == "__main__":
106+
main(int(argv[1]) if len(argv) > 1 else 1000)

bench/fasta.rbcvm

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import array;
2+
import string;
3+
4+
let IM = 139968,
5+
IA = 3877,
6+
IC = 29573,
7+
SEED = 42;
8+
9+
let seed = SEED;
10+
11+
function fasta_rand(max) {
12+
seed = (seed * IA + IC) % IM;
13+
return max * seed / IM;
14+
}
15+
16+
let ALU = string.chars(string.concat(
17+
"GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG",
18+
"GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA",
19+
"CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT",
20+
"ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA",
21+
"GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG",
22+
"AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC",
23+
"AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA",
24+
));
25+
26+
let IUB = string.chars("acgtBDHKMNRSVWY");
27+
28+
let IUB_P = [
29+
0.27, 0.12, 0.12, 0.27,
30+
0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02, 0.02
31+
];
32+
33+
let HomoSapiens = string.chars("acgt");
34+
let HomoSapiens_P = [
35+
0.3029549426680,
36+
0.1979883004921,
37+
0.1975473066391,
38+
0.3015094502008,
39+
];
40+
41+
let LINELEN = 60;
42+
43+
function repeat_fasta(seq, n) {
44+
let length = array.length(seq);
45+
let b = array.new(LINELEN);
46+
let i;
47+
for (i = 0; i < n; i = i + 1) {
48+
b[i % LINELEN] = seq[i % length];
49+
if (i % LINELEN == LINELEN - 1) {
50+
println(string.from_chars(b));
51+
}
52+
}
53+
if (i % LINELEN != 0) {
54+
println(string.from_chars(array.slice(b, 0, i % LINELEN)));
55+
}
56+
}
57+
58+
function random_fasta(seq, probability, n) {
59+
let length = array.length(seq);
60+
let i;
61+
let b = array.new(LINELEN);
62+
for (i = 0; i < n; i = i + 1) {
63+
let v = fasta_rand(1.0);
64+
for (let j = 0; j < length; j = j + 1) {
65+
v = v - probability[j];
66+
if (v < 0) {
67+
break;
68+
}
69+
}
70+
b[i % LINELEN] = seq[j];
71+
if (i % LINELEN == LINELEN - 1) {
72+
println(string.from_chars(b));
73+
}
74+
}
75+
if (i % LINELEN != 0) {
76+
println(string.from_chars(array.slice(b, 0, i % LINELEN)));
77+
}
78+
}
79+
80+
let n = 1000;
81+
if (array.length(argv())) {
82+
n = string.parse_integer(argv()[0]);
83+
}
84+
85+
println(">ONE Homo sapiens alu");
86+
repeat_fasta(ALU, n * 2);
87+
88+
println(">TWO IUB ambiguity codes");
89+
random_fasta(IUB, IUB_P, n * 3);
90+
91+
println(">THREE Homo sapiens frequency");
92+
random_fasta(HomoSapiens, HomoSapiens_P, n * 5);

0 commit comments

Comments
 (0)