perf(fiber): defunctionalize scheduler computations - #15723
Open
rgrinberg wants to merge 12 commits into
Open
Conversation
Reverse the mutable ivar reader chain in place and let the scheduler consume it through one reusable Readers job. This avoids allocating a Job for every resumed reader while preserving FIFO order. On a no-op @install self-build this reduced sampled promoted allocation by about 0.4M words. Signed-off-by: Rudi Grinberg <me@rgrinberg.com>
Represent continuations introduced by map and bind with typed frames while keeping a function frame as the escape hatch for arbitrary callbacks. Carry these continuations through effects and the scheduler without changing the public Fiber API. On a no-op @install self-build this reduced minor allocation by 14.1M words, promoted allocation by 1.1M words, the live heap by 0.6M words, and Cachegrind instructions by 0.8%. Native wall time remained neutral. Signed-off-by: Rudi Grinberg <me@rgrinberg.com>
Represent the continuations used by Fiber variable helpers and context unwinding directly instead of wrapping them in function closures. This keeps the function escape hatch for arbitrary callbacks while making common internal control transfers smaller. On a no-op @install self-build this reduced minor allocation by 3.0M words, promoted allocation by 1.0M words, and Cachegrind instructions by 1.5% on top of explicit map and bind continuations. Signed-off-by: Rudi Grinberg <me@rgrinberg.com>
Represent runs of up to three adjacent map continuations with one typed frame. This shortens promoted continuation chains and reduces scheduler dispatch without changing map order or the public API. On a no-op @install self-build this reduced promoted allocation by 0.25M words, peak heap size by 0.15M words, and Cachegrind instructions by 0.3%. Minor allocation increased by 0.46M words and native wall time remained neutral. Signed-off-by: Rudi Grinberg <me@rgrinberg.com>
Check that constructing a thunk fiber does not execute it and that running the same fiber twice executes the thunk twice. This guards the documented reuse semantics before changing the internal computation representation. Signed-off-by: Rudi Grinberg <me@rgrinberg.com>
Replace the internal CPS computation function with typed computation nodes and interpret computation and continuation spines directly in the scheduler. Keep user callbacks as opaque function payloads and pair internal primitive runners with explicit state instead of allocated closures. On a no-op @install self-build this reduced minor allocation by 23.8M words, promoted allocation by 1.2M words, the live heap by 1.1M words, and Cachegrind instructions by 1.1%. Alternating native measurements also showed lower wall time. Signed-off-by: Rudi Grinberg <me@rgrinberg.com>
Store deferred fork loops and fiber applications as typed work items instead of allocating thunk closures and wrapping them in scheduler continuations. Keep a function-backed work item for module-local loops that still require an opaque escape hatch. On a no-op @install self-build this reduced minor allocation by 1.0M words and slightly reduced promoted allocation and Cachegrind instructions. Signed-off-by: Rudi Grinberg <me@rgrinberg.com>
Replace per-child completion closures in parallel iteration, map-reduce, array mapping, fork-and-join, and Svar wakeups with typed continuation frames. Share one completion frame where all children perform the same update. On a no-op @install self-build this reduced minor allocation by 1.0M words, promoted allocation by 0.2M words, and Cachegrind instructions by 0.1%. Signed-off-by: Rudi Grinberg <me@rgrinberg.com>
Represent top-level, scoped, and map-reduce error continuations directly. This removes closure wrappers from error contexts and accumulates map-reduce errors through typed frames while retaining user-provided handlers as opaque callbacks. On a no-op @install self-build this reduced minor allocation by 0.43M words and promoted allocation by 0.25M words, with a small Cachegrind instruction reduction. Signed-off-by: Rudi Grinberg <me@rgrinberg.com>
Separate error handlers from the hot continuation representation and store map-reduce return state, handlers, and combiners in one context. Derive the active collection handler from that context and queue captured errors directly instead of reconstructing continuation jobs. Across no-op self-build targets this reduced minor allocation by 0.55M to 0.89M words and promoted allocation by 0.37M to 0.63M words. Cachegrind instructions fell by 0.8% to 1.4%, with neutral to improved native wall time. Signed-off-by: Rudi Grinberg <me@rgrinberg.com>
Store parallel array results, counters, and the final continuation once per map rather than repeating them in every child completion frame. Child frames now contain only the shared state and their array index. Across no-op self-build targets this reduced minor allocation by 0.32M to 0.58M words and promoted allocation by 0.05M to 0.12M words. Cachegrind instructions fell by 0.04% to 0.10%, with neutral native wall time. Signed-off-by: Rudi Grinberg <me@rgrinberg.com>
Use a dedicated computation and completion frame for [collect_errors] instead of constructing a generic map-reduce node followed by a map node. Caller callbacks remain opaque and error collection still uses the existing scope machinery. Across no-op self-build targets this reduced minor allocation by 0.19M to 0.33M words and promoted allocation by 0.02M to 0.04M words. Cachegrind and native wall time remained effectively neutral. Signed-off-by: Rudi Grinberg <me@rgrinberg.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replace Fiber's closure-heavy internal CPS machinery with typed representations for computations, continuations, deferred scheduler work, parallel completion, and error handling. The public Fiber API is unchanged, and caller-provided callbacks remain opaque function payloads.
The commits are ordered so that each representation change remains reviewable: first continuation and unwind frames, then computation and scheduler work nodes, followed by parallel and error-handling specializations. A test immediately before the computation rewrite records the existing reusable-thunk semantics.
Across warmed null self-builds, the complete stack measured:
@install@checkMajor-GC time fell by 2.00%, 4.78%, and 10.25% respectively, while peak RSS fell by 5.51%, 6.17%, and 4.41%.