Skip to content

Perf/cmin parallel processing#434

Open
0xalpharush wants to merge 2 commits into
rust-fuzz:mainfrom
0xalpharush:perf/cmin-parallel-processing
Open

Perf/cmin parallel processing#434
0xalpharush wants to merge 2 commits into
rust-fuzz:mainfrom
0xalpharush:perf/cmin-parallel-processing

Conversation

@0xalpharush

@0xalpharush 0xalpharush commented Jan 16, 2026

Copy link
Copy Markdown
Contributor

Add a cmin strategy speed which batches corpora into N workers and merges workers in pairs until single, minimized corpora is produced. In my experiment, this is about 10x faster and results in about 35% more files. The minset is still correct, but we are not adding the size constraint that libfuzzer has (it will replace 2 files with 1 if it covers the same edges but is smaller).

Initially, I tried implementing this like coverage which can be run in parallel batches and aggregated at the very end. It offered some performance benefits but still had to execute about half the initial corpus serially. In order to benefit from more rounds of parallel batches and not incur too much re-execution overhead, I exploited the interrupt-recovery mechanism in libfuzzer's control file to merge batches pairwise. For example, if we merge batch A and batch B, we effectively cache the features and coverage info of A, requiring libfuzzer to only re-run B to minimize A and B. While this is only approximating the global optima wrt to size, sometimes the speed is worth it.

Because each round experiences reduction and we can cache half the inputs each round, we re-execute inputs far less than if we were not to use the caching and perform pairwise merging.

size strategy

MERGE-OUTER: 2357 new files with 33046 new features added; 16554 new coverage edges

speed strategy

Merge worker 11: Merging "49" and "94"
MERGE-INNER: using the control file '/tmp/.tmp7No5Hf/49.control'
MERGE-INNER: 12551 total files; 9422 processed earlier; will process 3129 files now # Caching 
MERGE-OUTER: 2023 new files with 32403 new features added; 16547 new coverage edges
Final corpus: 3187 files

0xalpharush and others added 2 commits January 14, 2026 14:08
Implements parallel corpus minimization for `cargo fuzz cmin` with intelligent
control file reuse to minimize redundant test executions.

Key features:
- Parallel batch minimization: Splits corpus into batches processed concurrently
- Tournament-style merging: Pairwise merge of batches in log₂(N) rounds
- Control file optimization: Appends new file lists to existing control files,
  allowing libFuzzer to skip re-executing already-processed inputs
- Automatic temp directory cleanup: All temp files created under single root
- CPU detection: Defaults to number of available CPUs with --jobs flag
- Handles odd batch counts gracefully

Implementation details:
- Added `jobs` parameter to Cmin struct with CPU auto-detection
- Created helper functions: calculate_effective_workers, link_or_copy_files
- Minimum batch size of 100 files to avoid excessive parallelization overhead
- Uses hard links with fallback to copy for cross-filesystem compatibility
- Filters batch directories precisely (batch-N only, not batch-N-input/output)
- Merges control file entries to track processed files across tournament rounds
- Reuses batch directories to maintain control file path validity

Performance characteristics:
- Execution overhead: ~(1 + log₂(W)) × N executions for W workers
- Wall-clock speedup: W / (1 + log₂(W)) without redundancy
- Control file optimization provides 2x speedup per merge when files are redundant
- Scales better with more workers and larger corpora

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Switch cmin to a coordinator/worker merge queue backed by crossbeam channels so merging can begin as soon as batches finish rather than waiting for the whole Rayon phase. This keeps CPU busy by overlapping minimization and tournament merging, reduces lock contention, and avoids head-of-line blocking for large corpora. Also adds a size strategy to force a globally optimal single-worker minset.
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