aboutsummaryrefslogtreecommitdiff
path: root/docs/history/40-fatten/notes.md
blob: c7ff0fd00da2b94ec3625b8010ae3f5dfa709eba (plain) (blame)
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
# 40 — fatten

typed `new(T)` now stamps the header and zeroes the payload inside an o3 region, the same path `new(T)` takes outside one. a child store writes `p[-2] = owner` in the region when memdebug is off. a shared child keeps the owner it already has, and a store through null does not land. the store skips `fatten` when that value was just allocated, or came back from an o3 function whose type has a pointer. `fatten` still runs where o3 data reaches code that is not o3: a store into a normal local or a global, an argument to a function that is not o3, the call site where ordinary code calls an o3 function, `push` into a growable array, and the end of an o3 block. a call or a return from o3 to o3 does none of that. an untyped `new(n)` in o3 is still `new_raw`, with `-(n + 1)` in the type word and the requested words left uninitialized.

`tests/o3call.zc` now prints `0 0 4 23 55 node`: both the o3 caller and the ordinary caller see a stamped header. the fixpoint is 109799 words. the suite is 438 passed, 0 failed: interpreter, microcore, soft-float, the small and run-only maps, both virt boards, the arm64 jit and llvm.

## sieve

milliseconds per count, median of five slopes. the before column is `history/39-blocks`. this change does not touch the sieve's loops.

| path | before | after |
| --- | ---: | ---: |
| gcc -O3 -march=native, word flags | 0.167 | 0.151 |
| gcc -O3 -march=native -flto, byte flags | 0.080 | 0.084 |
| zc interpreter, plain, bounds-checked | 144.1 | 146.8 |
| zc interpreter, o3, bounds-checked | 12.46 | 12.75 |
| zc interpreter, o3, raw pointer | 7.97 | 8.09 |
| zc llvm, ZYHOT=1, o3 raw pointer | 0.227 | 0.233 |
| zc llvm, ZYHOT=1, o3 bounds-checked | 0.414 | 0.444 |
| zc arm64 jit, qemu-user, o3 raw pointer | 1.931 | 1.936 |

`bench/run.sh` timed the llvm raw pointer at 216 repetitions. one trial came out negative, and the median of that set is 0.172 ms (spread -0.12 to 1.14). the checked sieve's run was 45 repetitions and the median was -1.23 ms (spread -5.09 to 7.41). a slope from 4000 repetitions to 16000 on the same binary is 0.233 ms for the raw pointer (0.230 to 0.241) and 0.444 ms for the checked sieve (0.434 to 0.462). those two are the after column. they sit next to the previous long slopes, 0.227 ms and 0.439 ms.

## trees

milliseconds per tree of depth 12. the o3 `new` / `free` tree is the one this change is for. gcc on this run was 0.091 for malloc and 0.0144 for the arena.

| path | before | after |
| --- | ---: | ---: |
| gcc -O3 -march=native, malloc | 0.091 | 0.091 |
| gcc -O3 -march=native -flto, arena | 0.0144 | 0.0144 |
| zc interpreter, plain new/free | 75.69 | 72.97 |
| zc interpreter, o3 new/free | 158.6 | 64.89 |
| zc interpreter, o3 arena | 1.413 | 1.411 |
| zc llvm, ZYHOT=1, plain new/free | 7.58 | 7.42 |
| zc llvm, ZYHOT=1, o3 new/free | 17.68 | 6.49 |
| zc llvm, ZYHOT=1, o3 arena | 0.159 | 0.175 |
| zc arm64 jit, qemu-user, plain new/free | 44.87 | 44.12 |
| zc arm64 jit, qemu-user, o3 arena | 0.836 | 0.780 |

on the interpreter the o3 tree went from 158.6 ms to 64.89 ms, and the plain tree on the same run was 72.97 ms. on llvm the o3 tree went from 17.68 ms to 6.49 ms, and the plain tree was 7.42 ms. each node is one call to `new_t`, an owner store in the region, and the two recursive calls. the arena rows are the same shape as last time.