ReviewOS

zig-utils/zig-gc

Perf: batch sweep counter updates

#14
Closed chris opened this 9 days ago ·
9 days ago

Problem

The zig-js object_churn profile attributes substantial exclusive time to Heap.sweepPhaseLocked. Its reclaim loop currently updates live_cells, bytes_live, young_cells, and young_bytes on every dead cell, and updates the nursery counters again for each promoted survivor.

A completed full or minor sweep processes every young cell: survivors are promoted and dead young cells are reclaimed, so the nursery counters are always zero afterward. The live/reclaimed totals can likewise be accumulated locally while the existing allocation lock excludes mutations.

Proposed change

  • snapshot the cycle young-byte total before the sweep
  • accumulate reclaimed cell/byte totals in locals
  • retain the existing per-cell finalization, unlink, magic clear, and backing free order
  • commit live-byte/live-cell counters once after the loop
  • zero nursery cell/byte counters once after the loop
  • preserve per-cycle promoted/reclaimed statistics and collection thresholds exactly

Acceptance

  • focused nursery, full-sweep, finalizer, and parallel collector tests pass
  • zig-js focused GC/object-churn correctness tests pass with zero leaks
  • exact-parent alternating object_churn A/B shows a repeatable improvement
  • revert and close as not planned if timing evidence is neutral or regresses
9 days ago

Experimented locally and rejected; no commit was created.

Implementation:

  • accumulated reclaimed cell/byte totals locally
  • snapshotted the minor cycle young-byte total
  • committed live and nursery counters once after sweeping
  • preserved finalizer, unlink, magic-clear, and backing-free order

Correctness:

  • direct nursery filter: 7/7 passed
  • direct sweep filter: 5/5 passed, including full, minor, conservative, ephemeron, and parallel sweep cases

Exact-parent zig-js object_churn A/B:

  • zig-js parent a9523889
  • zig-gc parent b9b5a8c
  • 7 alternating process pairs
  • 3 samples per process
  • exact checksum 1030552128 throughout
  • candidate wins: 0/7
  • median of process medians: parent 217.196 ms, candidate 228.800 ms
  • paired median change: approximately +5.34%

Host load was high at about 12.9 on 11 logical CPUs, but alternating order did not rescue the candidate and every pair regressed. The local accumulators appear to cost more than the existing counter updates after optimization. This clearly fails the retention bar, so both worktrees were fully reverted and left clean.

Sign in to comment on this issue.