Skip to content

[0.32][Research] Find remaining ELF/cycle costs and measure the optimization frontier #40

Closed

Description

@a19q3

Accepted scope update — 2026-10-03

The maintainer authorized completion of the 0.32-related issues, including #36–#39 and #22. Independent review is waived for this work; no independent review is claimed. The earlier per-slice requirement for an independent boundary reviewer is superseded by that decision. Frozen budgets, compiler/checker agreement, adversarial execution evidence and final backend/CI gates remain required. This is not release or deployment authorization.

Implementation and acceptance are in progress. Existing checkboxes below remain authoritative for unfinished work.

Objective

Find the byte and execution costs that remain after 0.31, explain where they come from, and test how far they can be reduced while preserving the admitted contract semantics and independent artifact checking.

The deliverable is a measured set of implementation decisions and follow-up changes. Treat "as small and cheap as possible" as a search objective: publish the best measured alternatives for ELF size and execution cycles, including their tradeoffs. Do not claim a global optimum from a finite benchmark corpus.

Version assignment — 2026-09-24

Target: 0.32 research and optimization planning. This issue does not block 0.31.

Starting evidence

Use commit 6196a7fc60c5186240e3e9acf31bed2b764a580e as the source starting point. Its reproduction package contains exact source replay patches and the archived report pairs. Those measurements declare dirty, reconstructible source snapshots; the packaging commit must not be presented as their original measured clean commit. Produce a fresh clean-commit baseline for this research.

The archived comparator passes 6,782 comparable metrics without a regression. That establishes the specified comparisons, not that further savings are exhausted.

Concrete remaining questions:

  • All nine scalar fixtures retain the same static store count. scalar-overlap-260 has 529 stores before and after slot reuse; its loads change only from 820 to 818. These are whole-text instruction counts, not executed accesses or proof that the instructions are redundant.
  • Policy dispatch still scans tags linearly. Private argument copies and outer witness normalization remain. These were deliberate 0.31 exclusions.
  • The scalar allocator has conservative whole-function exclusions, and spills all parameters into distinct slots. Measure the coverage and cost of those fallbacks before relaxing them.
  • The immediate planner chooses between validated constructions and a fallback. Its tests establish correctness over the tested cases and no growth relative to the fallback; they do not establish shortest sequences over every legal encoding.
  • The ELF writer already uses 128-byte segment alignment. The old 3,976-byte padding removal has already happened and must not be counted as future savings.
  • The standalone decoder walks four-byte instructions and requires four-byte control-flow alignment. Compressed encodings would change this boundary substantially.

1. Attribute the remaining cost before choosing transformations

Build a per-artifact and per-execution breakdown:

Quantity Required distinction
Deployed ELF bytes Headers, padding, executable text, read-only data, and other retained sections; totals reconcile with file length
Generated text Entry/witness loading, tag dispatch, decoder, direct stubs, action bodies, helpers, and error paths; count shared code once
Executed work Instruction classes, load/store accesses, copied bytes, branch/call frequency, and syscall counts/charges, with VM/process identity
Cycles Transaction success, individual Script-group success/rejection, and unavailable outcomes; preserve the existing oracle
Other costs Witness and full transaction bytes; static stack bounds and observed per-VM stack peaks remain distinct

Use #36 for observed stack instrumentation. Extend measurement deliberately for executed memory traffic and per-PC cost attribution, with a versioned report contract and tests against small hand-calculated programs. A host execution trace is diagnostic: demonstrate that instrumentation does not change the artifact's verdict or authoritative cycle total. Account for additional syscall charges and process scheduling explicitly; do not assume an instruction histogram alone explains the full transaction cost.

The pinned CKB-VM 0.24.14 cost model assigns different costs to instruction classes. Fewer instructions or fewer ELF bytes therefore do not, by themselves, establish fewer cycles. Bind the actual node/VM versions and enabled instruction behavior in every experiment.

Separate unavoidable work required by the selected contract from implementation overhead. State assumptions behind any proposed lower bound. Identify the hottest executed sites and largest repeated code regions, then rank experiments by measured opportunity and verification effort.

2. Experiments and decisions

Every row below is a hypothesis to test, not an implementation claim or an accepted optimization.

Track First experiment Decision required
Register retention / spills — #39 Retain eligible scalar values within a basic block; remove demonstrably dead spills/reloads; classify parameter spills and allocator fallbacks Exact helper/call clobbers, live-register ownership, address-exposed exclusions, flush rules at joins/calls, and whether any wider allocator is justified
Dispatch — #37 Compare current linear routing with saved-selector routing and bounded comparison trees on the existing dense/sparse/high-u32 matrix Measured thresholds, tie-breaking, selector lifetime, exact target-set checks, and whether a jump table warrants a separate design
Witness loading and copies — #38 Measure normalization, parent-to-adapter copying and syscall work independently; test borrowing, bounded word copies, and staged loading separately Ownership, overlap, alignment, tail safety, buffer lifetime, nested/outgoing calls, and preservation of the complete admitted witness set
Repeated code and specialization Attribute repeated helpers, decoder tails, errors and generic instantiations; compare bounded outlining, inlining and specialization choices Complete equivalence keys, call overhead, source/proof attribution, and specialization limits; retain runtime checks whose redundancy is not established
Pure IR and CFG simplification Audit existing constant folding, inlining and dead-code passes first; prototype missed pure common expressions, redundant stack traffic, and branch simplifications Which effects, traps, overflows, resource operations and error-order dependencies prohibit rewriting; how eliminated checks remain justified
Immediate and address construction Search bounded literal domains and real emitted constants for shorter legal sequences; compare rematerialization with reuse or constant-pool loads Explicit search grammar/bounds, register pressure, pool bytes/relocations, branch relaxation, and instruction-set scope; distinguish a proved bounded result from sampled evidence
ELF and data layout Inventory remaining section/padding/string/constant costs and test legal deduplication/layout changes Loader and independent-checker requirements, exact accounting, deterministic output, and whether a format change is worth its compatibility cost
Compressed instruction feasibility Count actually encodable sites using their real registers/immediates; construct a small isolated mixed-width prototype only after target verification Pinned CKB support, a bounded instruction subset, assembler sizing/relaxation, decoder/control-flow alignment, source maps and versioned checker migration

For compressed instructions, the RISC-V C specification describes 16-bit encodings with operand restrictions. Its general code-size estimates are not CellScript measurements. First verify the exact supported CKB target; do not enable compressed instructions in the current production backend merely because the ISA has them. Measure whole-ELF effects after relaxation/alignment and authoritative cycles separately.

Witness/ABI redesign is a separate compatibility track. If the byte breakdown justifies one, propose a versioned format, canonical codec, migration rules and builder/checker changes in its own RFC. Keep the existing wire format as the baseline. Archive compression of release downloads does not reduce the deployed executable by itself; a runtime unpacking design would need its own measured execution and verification contract.

3. Experimental design

  1. Reproduce the current baseline with exact compiler/checker commits, source and ELF hashes, dependencies, toolchain, strip tool, profiles, target and VM configuration. Keep Cargo build directories isolated between source checkouts.
  2. Retain all existing matched Rust samples, 18 growth rows, 41 expanded policy rows, nine scalar/call fixtures, every action/rejection observation, and six multi-Script cases. Preserve fixed budgets and measurement availability rules.
  3. Add focused probes before tuning: repeated versus distinct generic instantiations; non-overlapping versus simultaneously live scalars; joins/backedges/calls; immediate, offset and branch-distance boundaries; first/last/unknown tags; exact/truncated/over-bound witnesses and malformed late records. Include held-out application-shaped fixtures so gains are not confined to a synthetic pattern.
  4. Run one transformation at a time. After individual results, test interactions: register retention × outlining, slot placement × compressed eligibility, dispatch × immediates, borrowing × nested calls, and code layout × branch relaxation. Re-measure the combined candidate rather than adding isolated savings.
  5. Keep current Rust references unchanged for continuity. Add further matched Rust examples where coverage is missing, with equivalent checks and accepted/rejected inputs. Record ISA, build and stripping differences explicitly. Any separately retuned Rust reference must be labeled and retained alongside the old reference.
  6. Publish raw artifacts, source replay/clean identities, per-fixture deltas and rejected experiments. Include all exercised rejection paths and worst observed rows. Label a corpus maximum as observed, not a bound over all possible inputs.

4. How to choose the result

Maintain the non-dominated alternatives: a candidate belongs on the measured frontier when another tested candidate does not improve it across all the chosen cost dimensions. Keep per-fixture results visible; a single average can hide a regression.

  • The default production candidate must preserve existing ceilings and comparable outcomes. Keep the existing no-regression rule unless an exact, documented tradeoff is accepted by the maintainer and compiler/checker boundary reviewer.
  • Decide whether the evidence warrants separate size-oriented and cycle-oriented profiles. These are proposed policies, not new CLI flags promised by this issue. Any accepted profile needs deterministic selection, explicit budgets and the same semantic contract.
  • Do not preselect a dispatch threshold, savings percentage or code-size/cycle exchange rate. Reject experiments that save too little to justify their checker/maintenance cost, and retain the measurements explaining that decision.
  • Keep source editions, Cell/resource lifecycle rules, admitted inputs, witness ownership, error propagation and external-verifier trust boundaries fixed in the initial experiments. Any proposed semantic or wire change gets a separate decision.
  • Changed machine shapes require coordinated lowering/source-map/checker updates, negative mutations and regenerated artifact identities. Compiler self-checks alone are insufficient. Existing deployments retain their old identities.

Work order and completion

Start with attribution and clean baseline reproduction, then prioritize #39, #37 and #38 using that evidence. Run code-sharing/pure-IR/immediate probes next. Treat compressed instructions and wire changes as separately gated investigations. Each implementation slice must name an implementer, an independent boundary reviewer, its target fixtures and acceptance budget before merge.

  • Publish an inventory marking each opportunity as already implemented, unfinished, excluded for a stated reason, or unmeasured. Link each item to code and owning issue.
  • Produce reproducible byte and execution-cost attribution, with explicit coverage and unavailable categories.
  • Give every experiment above an adopt/reject/defer decision supported by results or a concrete blocker; create narrowly scoped implementation issues where needed.
  • Publish the measured frontier and select the default/profile policy with recorded tradeoffs.
  • Test selected transformations together and preserve the baseline/Rust/adversarial comparisons without regenerating budgets to make them pass.
  • Update independent machine contracts and mutation tests for accepted backend changes; pass ./scripts/cellscript_gate.sh backend and ./scripts/cellscript_gate.sh ci. Use the full release gate and fresh downstream bundles before publication.
  • Finish with a residual-cost report: what remains, why it remains, which search spaces were exhausted under stated bounds, and which remain untested. Completion means the agreed research questions are answered and implementation work is explicitly tracked; it does not mean universal optimality has been proved.

Related: #30, #31, #32, #33, #34, #35, #36, #37, #38, #39.

Activity

  1. added this to the 0.32 milestone on Sep 24, 2026
  2. changed the title [-][Post-0.31][Research] Find remaining ELF/cycle costs and measure the optimization frontier[/-] [+][0.32][Research] Find remaining ELF/cycle costs and measure the optimization frontier[/+] on Sep 24, 2026
  3. a19q3 commented on Sep 27, 2026

    @a19q3
    CollaboratorAuthor

    Accepted immediate-construction slice: #41, implemented on 0.32 at 8017a7bd.

    Decision: adopt the validated low-mask candidate only on a strict improvement. Constructing 2^n - 1 for n=31..63 now uses addi rd, zero, -1; srli rd, rd, 64-n: two real instructions instead of three, with the same result and no extra register. Existing shorter/equal plans remain unchanged.

    The archived evidence binds clean baseline 54d639a7 and clean implementation 0e544ce1, passes 6,782 comparable metrics without regression, and retains the raw report pairs and checksums. The focused executed saving is four instruction bytes and one cycle per materialization. Whole-program gains are small and fixture-specific; alignment can absorb the file-size saving.

    This does not select general immediate search, register retention, dispatch redesign, witness changes, compressed instructions, or any other candidate from this umbrella. 0.30/0.31 remain unchanged. Final gate receipts are tracked in #41. Implementation-author engineering evidence does not substitute for the independent boundary review required before merge or for release approval.

  4. a19q3 commented on Oct 5, 2026

    @a19q3
    CollaboratorAuthor

    0.32 research closure progress; this issue remains open while the final #39 archive and decision update are published.

    The published research report retains the clean baseline, 1,707-run attribution, measured frontier, residual sites and historical gate identities. #36, #37 and #38 are now closed with individual evidence comments. Their outcomes are measured instrumentation or explicit retain/reject/defer decisions, not automatic adoption of every proposed optimization.

    #39's second bounded candidate was measured locally and rejected: four of 1,707 executions save one cycle, without ELF/store/stack savings. Its exact source replay and raw reports are prepared for publication. No register-retention change was applied to the default backend.

    The current implementation's comparison with the published cost baseline still passes all 6,782 comparable metrics with unchanged budgets and Rust references. Wider CSE, outlining, constant-pool search, borrowing and compressed instructions retain their explicit semantic/checker blockers; a finite evaluation does not claim those transformations are implemented or universally unhelpful.

    Validation boundaries remain explicit. The historical clean research baseline has archived backend/CI passes. The latest interface/entry-scoping work for #28 passed compiler/checker tests, Clippy, cost comparison and the full syntax matrix, but its complete backend gate stopped at the stateful harness's clean-committed-source prerequisite. It has no new full backend-pass claim until that replay completes. Release publication and public deployment remain separate.

  5. a19q3 commented on Oct 10, 2026

    @a19q3
    CollaboratorAuthor

    Completed within the 0.32 implementation scope. This closes the 0.32 cost research umbrella: clean baseline, cost attribution, per-track adopt/reject/defer decisions, measured frontier and residual report are published in RESEARCH.md. This is not a release/public-deployment claim and does not claim global optimality from the finite corpus.

    #36–#39 now carry individual closure evidence on their issues. Closing this umbrella answers the agreed research questions with implementation work explicitly tracked; it does not convert unmeasured transformations into rejected experiments or implemented features.

  6. a19q3 commented on Oct 10, 2026

    @a19q3
    CollaboratorAuthor

    Closing as completed: attribution, per-track decisions, measured frontier and residual report published; default policy selected. Evidence: #issuecomment-6099391394. Sub-coordination issues #36–#39 are closed individually.

  7. added a commit that references this issue on Oct 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions