Repository navigation
perf(runtime): note the chain being evaluated without copying its slices into every context - #1745
Merged
Merged
Conversation
…ces into every context Co-Authored-By: jason.han <hanhuijun@gmail.com>
…k requires Co-Authored-By: jason.han <hanhuijun@gmail.com>
Co-Authored-By: jason.han <hanhuijun@gmail.com>
Contributor
Author
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
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.
What and why
AssignmentLoopStepallocates 971 KB per step on the 0.12.0 candidate against 921 KB on 0.11.0's source built with the same toolchain (six rounds, bytes exact; allocation counts are equal). Half of that is the size ofEvalContext, which the runtime copies for every nested evaluation: #1514 addedchainStaticwith two slice headers (the chain's segments and the declarations they name, 48 bytes), and #1461 added theopenInputsflag in its own padded word, so a context grew from 152 to 184 bytes.This PR keeps what both merges compute and shrinks how the context notes it:
chainStaticholds a pointer to the chain's last segment, its length and a pointer to the memoizedchainDeclsinstead of two slice headers;chainDeclarationsForcompares the last segment's address as before, so the whole-chain / suffix distinction is unchanged. TheModel.chainDeclarationsmemo stores*chainDecls, so the memoized slice is shared, not copied, into each context.openInputssits beside the behavior-body flag so the two share a word.EvalContextis 152 bytes again. Root cause: the per-context copy of chain state (#1514) and padding (#1461); correctness of both merges is kept.A/B, six rounds (
go test ./internal/exec/runtime -bench . -benchmem -count 1× 6,benchstat; pre-#1514 / #1514 / candidate1c6bb1972/ this branch; same host, "Intel(R) Xeon(R) Processor", 8 CPUs; bytes and allocations exact)AssignmentLoopStepB/opAssignmentLoopStepallocs/opDerivedReadWriteReadB/opDerivedReadWriteReadallocs/opResidual, stated in the fragment:
AssignmentLoopStepstays 13 Ki above pre-#1514 (the context's new state — the chain note and the open-inputs flag — is what the merges needed); the remainingDerivedReadWriteReadbytes are #1619's order marks on derived reads, a separate PR (perf/derive-marks-footprint). No sec/op claim: the host ran a fullgo test ./...gate alongside rounds 1–3 and the timing columns carry ±100–250 % spread.Memory acceptance
runtime.test -test.bench '^BenchmarkAssignmentLoopStep$' -test.benchtime 300x, candidate and fix built the same way, three cold runs each, interleaved (/usr/bin/time, 8 CPUs):Hard cap: under
ulimit -v 4000000both pass (candidate 122 MiB, fix 118 MiB peak RSS). Underulimit -v 2000000both revisions die as the Go runtime reserves its arenas (runtime: out of memory: cannot allocate 4194304-byte block (24 MB in use)), before any model is loaded, so that cap says nothing about the change. Whole binary,sysml -validateover the 12 086-element generated model, three cold runs: 198 / 198 / 198 MiB candidate, 200 / 187 / 200 MiB fix, 0.24 s both;tests/stressmodelFleetInstantiate/512andLoad/512stay inside their GC-pacing spread (1.14–1.47 GiB and 1.27–1.36 GiB on both). Resident memory is not what this change recovers: it is 23 KB of allocation volume per step, and the PR does not claim an RSS change.How it was verified
TestChainDeclarationsAreResolvedOncePerModel(new,internal/exec/runtime/chain_declarations_memo_test.go) pins that a chain's declarations are resolved once per model and that the contexts evaluating it share the memoized entry.go test ./...below).Gate
(corpora present: training examples, pilot corpora, spec examples, pilot library XMI, PSSM suite, with their
OPENSYSML_REQUIRE_*variables set.)Checklist
go build ./...,go vet ./...,gofmt -l .(empty),go test ./...pass locally (above);make lintnot run (the gate above is the repository's definition of done)EvalContext's layoutchanges/unreleased/eval-context-size.fixed.mdmake docs-countsrun if a gate count moved — no count movedLink to Devin session: https://nasa-jpl-demo.devinenterprise.com/sessions/15408827f8104c7fbbdbd1b2c852ed2c
Open in Devin Desktop: https://nasa-jpl-demo.devinenterprise.com/desktop/session/15408827f8104c7fbbdbd1b2c852ed2c?variant=devin
Requested by: @HuiJun