perf(runtime): inline the fast path of torb_retain, torb_release and torb_make_unique (P12) #444
Loading…
Reference in a new issue
No description provided.
Delete branch "loop/59-inline-refcount-fastpath"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #59
What
Round P12 (docs/PERFORMANCE.md finding 13 again): the common case of
torb_retain,torb_releaseandtorb_make_uniqueisstatic inlineinruntime/include/torb.h; every other case is the out-of-linetorb_retain_slow,torb_release_slowandtorb_make_unique_slowinruntime/memory.c(NULL, immortal, shared/threaded, the last count with the drop depth bound, the zero-count panic, the copy). Semantics ofmemory.care unchanged.Three commits:
fix(benchmarks)(run.sh --allocations did not linkruntime/os/and the threads, so the allocation column was empty),perf(runtime),docs(performance). The fix is a prerequisite for the allocation check of this round; it could not be folded into either of the two.Measurement
One forge CI job, one runner (Linux 6.8, AMD EPYC Genoa, 16 processors, gcc 13.3.0,
-O2),benchmarks/run.sh --allocations, RUNS=9, passes A B C D then D C B A, fastest of the eighteen runs. Variants: A as is, B retain inline, C B plus the unique test, D all three. Base:mainatff037c08. The temporary measurement job and script are not part of this branch (they were removed from the history; the job was a push-triggered workflow on this branch's earlier commits).arithmeticcall-depthwrapperclosurelist-indexlist-iteratechain-walkpipelinerecord-writenested-writeaccumulateinterpolationmap-countmap-writecons-stackarray-stackbankers-queuering-listarray-frontbuffer-writearray-writebuffer-swap-removearray-swap-removeheapheap-sortedbinary-trees(game)Allocations: identical in all four variants for every row.
Decision (rule from #59)
At least 5% faster on two named rows, no named row more than 3% slower, conformance green on both back ends.
D lands. Conformance on both back ends and the runtime tests: this PR's CI.
Code size
-O2object of the emittedprogram.c: list-iterate 1378 bytes text in all variants (+0), pipeline 3937 to 4677 (+740), record-write, list-index, map-count unchanged. Text ofruntime/*.cobjects summed: 440971 (A) to 443539 (D), +2568 (+0.6%);machine.c+128,task.c+1544.Test
Locally: no C compiler on this host, so nothing built here; the gates run in this PR's CI.
-fltowas not tried (out of scope per the issue). The VM's kernel (machine.c) is unchanged and calls the same names, which are now the inline functions over the same slow entry points.Seed impact: none. No syntax, native, or name looked up by string.
1a2987b4c07d4fe624a4Approved.
memory.coriginals.torb_retain: non-NULL and count < SHARED, plain +1 (the same result as before, immortal and shared go to the slow path).torb_release: only 1 < count < SHARED is decremented inline, so the last count, the zero-count panic, immortal, shared/atomic and the drop-depth bound all stay intorb_release_slow.torb_make_unique: the(count & ~SHARED) == 1test equalstorb_is_unique, an immortal count masks to 0x7FFFFFFF and still copies. The count is read relaxed, astorb_count_ofdoes. No place takes the address of the three symbols; the C emitter and the VM kernel call them by name, so they pick up the inline versions.run.sh --allocationslink fix is a stated prerequisite for the allocation check.Non-blocking: the PR body says nothing was built locally; fine since CI is authoritative, but a one-line runtime test that calls the
_slowentry points directly (zero-count panic, immortal) would pin the contract that they are complete functions.