ReviewOS

zig-utils/zig-gc

Perf: batch same-kind cell publication under one allocation lock

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

Parent consumer issue: https://github.com/zig-utils/zig-js/issues/97

Post-quickening profiling of the exact zig-js shared object_churn row (ReleaseFast, 8 lanes) finds Heap.create at 14,907 top-of-stack samples in a five-second sample, versus GcCellBacking.allocFn at 1,936 and headerForPayload at 1,371. Heap.create serializes every parallel allocation through the single alloc_lock even when a caller can safely initialize several same-kind cells before its next safepoint.

Scope:

  • add a general same-kind batch creation API that allocates private slabs first and publishes their initialized headers/list/counters under one metadata lock;
  • preserve single-create behavior and allocator/OOM recovery;
  • preserve nursery counters, born-grey/concurrent-mark deferral, exact payload alignment, all-list integrity, and cleanup of partial allocations;
  • add direct tests for normal, nursery, OOM/partial allocation, and parallel allocation behavior;
  • consume the API from zig-js fixed-shape allocation quickening and prove exact-parent direct/shared gains;
  • pass zig-gc tests plus zig-js semantic, GC, TSan, and threadfuzz coverage.

Acceptance:

  • batch publication takes one alloc_lock acquisition for N successfully allocated cells;
  • no leaked slabs or partially published cells on failure;
  • exact live/young byte and cell accounting;
  • material improvement in the eight-lane shared object-churn row without direct regression.
9 days ago

Implemented and pushed as Chris with no coauthors:

  • 65441fe — general same-kind Heap.createBatch, one-lock publication, exact accounting/parallel/OOM tests, and README usage
  • 3183d08 — prefix-return OOM ordering so consumers commit successful cells before retry/recovery
  • 179ffe2 — inline the single-cell helpers to preserve direct-path codegen
  • zig-js consumer 84d2f9f4 — batch up to 16 fixed-shape object allocations per shared quick-loop checkpoint

Validation/evidence:

  • zig-gc full unit suite and full TSan suite passed locally; the OOM tests caught and prevented publication of uninitialized output slots during development.
  • zig-js focused semantic/GC tests and focused TSan tests passed, including a real four-Thread assertion that at least 2,048 cells used the batch API.
  • zig-js full validation passed 761/761 tests with zero leaks plus 7/7 comparison-harness tests.
  • Exact-parent direct object-churn A/B: 195.410 ms -> 192.974 ms median (-1.25%, candidate won 5/7 pairs), checksum exact.
  • Exact-parent shared 8-lane A/B: 902.841 ms -> 393.507 ms median (-56.42%, candidate won 7/7 pairs), checksum exact.
  • The validated 1,540-sample publication at zig-js 3d790a60 reduced shared 8-lane object churn from 18,472.129 ms to 12,368.464 ms (-33.0%) and improved scaling from 0.21x to 0.31x amid high published dispersion.

Remote CI was missing from zig-gc/main, so #16 restores it in a659d66. Current two-job unit/20x-TSan run: https://github.com/zig-utils/zig-gc/actions/runs/29364477008

All #15 API, correctness, accounting, and consumer-performance acceptance items are satisfied; I will close this after the restored remote gate is green.

9 days ago

Remote dependency gate is green after restoring it to main and fixing explicit Linux libc linkage: https://github.com/zig-utils/zig-gc/actions/runs/29364720539

  • unit: success
  • 20-iteration TSan: success

Together with the previously posted exact-parent consumer A/B and full zig-js validation, all acceptance criteria are satisfied.

Sign in to comment on this issue.