Skip to content

partition shuffling#294

Open
conradludgate wants to merge 4 commits intotaiki-e:mainfrom
conradludgate:partition-shuffling
Open

partition shuffling#294
conradludgate wants to merge 4 commits intotaiki-e:mainfrom
conradludgate:partition-shuffling

Conversation

@conradludgate
Copy link
Copy Markdown

An unsolicited idea I had, turns out to be an alternative to #266 and a potential solution for #265 and #255 when given a random seed.

I noticed that in our pretty heavy workspace, of our 4 partitions, 2 of them would finish within 5 minutes while the other 2 would take 20 minutes to complete.

This adds a --partition-seed <random string> flag that shuffles the partition assignment in an attempt at getting an even amount of load across partitions. The seed (rather than pure random) is for consistency within re-runs and across partitions. When the flag is not provided, the partitions are left unshuffled, which preserved the existing behaviour.

Current notes:

  1. This requires --partition and will error without (style choice, can change this)
  2. This manually implements a stable prng/hash to avoid any dependency changes, happy to take a dep on rand though.

The code was written with the assistance of Claude Opus 4.7 Extra High Effort. Idea and design is entirely my own.

The default --partition M/N divides invocations into contiguous chunks
in workspace-member order, which leaves heavy members biased toward the
same partition across CI runs. --partition-seed <SEED> hashes the seed
string with FNV-1a and uses it to seed a SplitMix64-driven Fisher-Yates
shuffle of the assignment, balancing load across partitions while
keeping each partition exactly the same size as the unseeded version.
partition_seeded verifies that the same seed produces identical
partition decisions across runs and that the union of "running"
commands across all M/N partitions covers every invocation exactly
once with the unseeded chunk sizes (6, 6, 5).

partition_bad gains a case for using --partition-seed without
--partition.
- Reformat with nightly rustfmt: uppercase hex literals in fnv1a_64
  (hex_literal_case = "Upper") and collapse a few multi-line blocks
  (use_small_heuristics = "Max").
- Add PRNG to project-dictionary.txt; it appears in a SplitMix64 doc
  comment.
@conradludgate
Copy link
Copy Markdown
Author

I did some proper measurements of the last 41 cargo-hack runs with our 155 feature-powerset targets:

Partition Mean Std Min Max Std/Mean
1/4 12m 11s 37s 10m 55s 13m 24s 5.0%
2/4 26m 1s 94s 23m 18s 28m 50s 6.0%
3/4 20m 1s 88s 17m 13s 22m 50s 7.3%
4/4 10m 27s 31s 9m 21s 11m 21s 5.0%

I've done 3 additional test runs using this --partition-seed change:

Partition Previous Mean Run 1 Run 2 Run 3
1/4 12m 11s 18m 43s 7m 54s 12m 10s
2/4 26m 1s 12m 27s 9m 04s 14m 26s
3/4 20m 1s 14m 42s 8m 02s 13m 3s
4/4 10m 27s 12m 39s 13m 25s 8m 19s

It's clear the load balancing is still not perfectly uniform, but I'm pretty confident that it has improved the status quo.

@conradludgate conradludgate mentioned this pull request Apr 18, 2026
2 tasks
@conradludgate
Copy link
Copy Markdown
Author

One thing I have noticed: this implementation still runs through all the tests in order, so this does not solve the issue for #265. I'm happy to adjust the code to account for that if desired (and to make this feature work without needing --partition)

@conradludgate
Copy link
Copy Markdown
Author

Ok. I have a PoC locally for --shuffle $(uuidgen) which works without needing --partition, and it could be paired with a --limit N flag in the future.

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.

1 participant