Skip to content

Add multi-Ractor memory benchmarks - #538

Open
eightbitraptor wants to merge 4 commits into
mainfrom
mvh-gc-ractor-benchmarks
Open

eightbitraptor wants to merge 4 commits into
mainfrom
mvh-gc-ractor-benchmarks

Conversation

@eightbitraptor

Copy link
Copy Markdown
Member

Add three benchmarks that expose pathological memory behaviour with
multiple ractors.

  • ractor-dead-set: every ractor builds a large live set and terminates;
    their final live sets cannot be reclaimed by a full GC.

  • ractor-idle-garbage: every ractor builds and drops a large set, then
    idles without allocating; the garbage cannot be swept while they idle.

  • ractor-msg-backlog: unshareable payloads flood the queues of gated
    consumer ractors, duplicating data per consumer.

benchmarks.yml marks them ractor_only with default_harness
harness-ractor-mem, which overrides the --category ractor default.

@luke-gruber

Copy link
Copy Markdown
Collaborator

I think we should look into using the --ractor-gc flag along with the ractor harness for the new GC benchmarks. Getting that PR merged first is probably a good idea.

@luke-gruber luke-gruber left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's merge --ractor-gc first and then try to use that for these benchmarks.

@eightbitraptor
eightbitraptor force-pushed the mvh-gc-ractor-benchmarks branch 2 times, most recently from 96776f1 to 929e233 Compare October 6, 2026 16:34
@eightbitraptor
eightbitraptor marked this pull request as ready for review October 7, 2026 08:48
These belong with the rest of the Ractor GC sampling helpers.
The ractor harness runs the benchmark block inside every Ractor it
spawns. That doesn't work for benchmarks that need to coordinate their
own Ractors from the main Ractor, for example to send them messages,
or to keep them alive while we measure memory.

With run_benchmark(n, scenario: true) the harness calls the block once
per trial on the main Ractor with the Ractor count, and the block
spawns its own Ractors. If the block returns a proc, the harness calls
it after the memory measurement so idle Ractors can be cleaned up.
Scenario mode doesn't run count 0 or a warmup.

Each trial records the time, the RSS retained after a full GC compared
to a baseline taken before the first trial, and the peak RSS while the
block ran. We use GC.start(global: true) when it's available, because
otherwise only the main Ractor is collected on Ractor-local GC builds.

The harness can't tell which Ractors are the workers, so with
--ractor-gc each worker wraps its body in measure_worker_gc and the
main Ractor passes the samples to record_worker_gc.
These use the scenario mode to measure how much memory we fail to
reclaim when multiple Ractors are involved.

- ractor-dead-set: each Ractor builds a large live set and exits.
- ractor-idle-garbage: each Ractor builds a large set, drops it and
  then sits idle, so nothing sweeps it.
- ractor-msg-backlog: the main Ractor floods sleeping consumers with
  unshareable messages, so every consumer holds its own copy.
With Ractor GC data, the comparison GC summary was over 250 characters
wide.

This commit splits it into a GC time ratios table and a GC counts
table. The "ratio" and "worker sum" labels move out of the column
headers and into the table titles. Columns with no data in any row are
hidden and listed under the table.

global/iter is now shown as a count instead of a ratio. It's a GC
count, and the legend says the ratios are GC time.
@eightbitraptor
eightbitraptor force-pushed the mvh-gc-ractor-benchmarks branch from 929e233 to 085ad51 Compare October 7, 2026 11:51
@eightbitraptor

Copy link
Copy Markdown
Member Author

This PR now uses the ractor-harness with --ractor-gc instead of the harness-ractor-mem that was originally implemented from before --ractor-gc was merged. But in doing the refactoring work here I noticed a couple of other issues with the way Ractor and GC benchmarks work which I'd like to get merged first. They've been addressed in #541 and #544

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants