whitepaper §6.6.3: collaborative adaptive meta-GC results

Adds §6.6.3 "Collaborative Meta-GC: From Greedy to Adaptive" with
the three-workload benchmark (friendly / hostile / mixed × greedy
/ adaptive). Honest read of the numbers:

  friendly  greedy    732 ms  1000 resets, 0 escapes
  friendly  adaptive  691 ms  1000 resets, 0 escapes       (-6%)
  hostile   greedy    568 ms     0 resets, 1000 escapes
  hostile   adaptive  607 ms     0 resets, 1000 escapes, 11 skipped (+7%)
  mixed     greedy   1981 ms    17 resets, 1983 escapes
  mixed     adaptive 1694 ms    14 resets, 1986 escapes, 2 skipped  (-17%)

Adaptive wins on friendly (-6%) and mixed (-17%, the policy's
design target). On fully hostile workloads implicit GC fires 982
of 1000 arenas before the dispatcher sees them, so the signal is
drowned and greedy happens to edge adaptive by ~7%. Section
explicitly calls out the collaborative-but-local structure
(shared state on arena_active + EMA + countdown, decisions made
locally by each component) and credits the benchmark work with
surfacing two real correctness bugs in the conservative stack
scan — 24-byte strings misread as env nodes, 40-byte strings
misread as 25-element vectors — both now fixed.

Also:
  - meta-gc-policy.dot rewritten to show the adaptive gate
    (rate > 50% + probe countdown) before the greedy verify path;
    new skip branch, new EMA annotations on edges.
  - §6 reproducibility list + Makefile bench-gc-adaptive target.
  - PDF rebuilt at 2.64 MB.

137 asm no-GC + 137 asm GC + 189 shared functional tests pass
against the new asm.
This commit is contained in:
russell@unturf.com 2026-04-18 11:35:27 -04:00
parent 3d55092037
commit 3f1b1bc0ab
6 changed files with 2109 additions and 1308 deletions

View file

@ -1,33 +1,44 @@
// Meta-GC decision policy — 2026-04-18
// Meta-GC decision policy — 2026-04-18 (adaptive)
// "A diagram is worth 10,000 words." — russell@unturf.com
digraph meta_gc {
rankdir=LR
node [shape=box, style="filled,rounded", fontname="Helvetica", fontsize=10]
edge [fontname="Helvetica", fontsize=9]
label="Meta-GC decision at (with-arena thunk) exit"
label="Meta-GC decision at (with-arena thunk) exit — adaptive + greedy layers"
labelloc=t
fontsize=13
fontname="Helvetica Bold"
enter [label="Arena enter\nsnapshot %r15\nactive ← 1\nfreelist OFF" fillcolor="#fff3cd"]
thunk [label="Run thunk\n(apply_proc_raw)\n+ zero volatile regs" fillcolor="#d4edda"]
thunk [label="Run thunk\n(apply_proc_raw)\nzero volatile regs" fillcolor="#d4edda"]
gate1 [label="arena_active\nstill 1?" shape=diamond fillcolor="#fab1a0"]
verify [label="Mark phase\n(globals, syms,\nstack, + result)" fillcolor="#81ecec"]
abort [label="SKIP reset\n(implicit GC ran)\nEMA += escape" fillcolor="#fab1a0"]
gate_rate [label="adaptive mode\n& rate > 50%?" shape=diamond fillcolor="#ffd6a5"]
gate_probe [label="probe\ncountdown > 0?" shape=diamond fillcolor="#ffd6a5"]
skip [label="SKIP verify\nlet heap grow\nnext overflow → full GC\nEMA += escape" fillcolor="#fd9644"]
verify [label="Verify\nmark phase\n(globals, syms,\nstack, + result)" fillcolor="#81ecec"]
gate2 [label="Mark in\n[snap, r15)?" shape=diamond fillcolor="#81ecec"]
reset [label="BULK RESET O(1)\n%r15 ← snap\nresets++" fillcolor="#00b894" fontcolor=white]
escape [label="SWEEP FALLBACK\ngc_sweep full\nescapes++" fillcolor="#e17055" fontcolor=white]
abort [label="SKIP reset\n(implicit GC ran)\nescapes++" fillcolor="#fab1a0"]
reset [label="BULK RESET O(1)\n%r15 ← snap\nresets++\nEMA += 0" fillcolor="#00b894" fontcolor=white]
escape [label="SWEEP FALLBACK\ngc_sweep full\nescapes++\nEMA += 1" fillcolor="#e17055" fontcolor=white]
ret [label="Return result\n(arena-stats)" fillcolor="#dfe6e9"]
enter -> thunk -> gate1
gate1 -> verify [label="yes"]
gate1 -> gate_rate [label="yes"]
gate1 -> abort [label="no"]
gate_rate -> verify [label="no (rate low\nor greedy)"]
gate_rate -> gate_probe [label="yes"]
gate_probe -> skip [label="yes\n(-- countdown)"]
gate_probe -> verify [label="no (probe,\nreset countdown)"]
verify -> gate2
gate2 -> reset [label="no"]
gate2 -> escape [label="yes"]
reset -> ret
escape -> ret
skip -> ret
abort -> ret
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Before After
Before After