Cache-line false sharing linter for Rust structs.
Finds Rust structs where atomic or contended fields share a cache line with other fields. This is potential false sharing, not proven — snarf detects the layout but not runtime behavior, so you decide which fields are actually contended.
The Slowdown That Doesn't Show Up in Profiles — why this matters.
cargo install cargo-snarf
cargo snarf
No output means no issues found. If snarf finds contended fields sharing a cache line, it prints a layout diagram and exits non-zero. In a workspace it discovers all crates automatically.
snarf requires nightly Rust to get exact type sizes via cargo +nightly build -Zprint-type-sizes. Install it:
rustup toolchain install nightly
- name: Cache-line sanity check
run: |
rustup toolchain install nightly --profile minimal
cargo install cargo-snarf && cargo snarfFor PR annotations without blocking:
- name: Cache-line annotations
run: |
rustup toolchain install nightly --profile minimal
cargo install cargo-snarf && cargo snarf --format github --warn-onlyThis repo runs snarf on itself — see ci.yml.
| Flag | What it does |
|---|---|
--strict |
Warn on all multi-field cache lines, not just contended ones |
--format json |
Machine-readable output |
--format github |
GitHub Actions annotations on the PR diff |
--warn-only |
Report issues but exit 0 |
--threshold N |
Minimum fields per line to warn (default: 2) |
--line-size N |
Cache line size in bytes (default: 64, use 128 for Apple M-series) |
--no-send-sync-check |
Warn even on !Send/!Sync structs (see below) |
--color never |
No ANSI escape codes |
By default snarf only warns when an Atomic*/Cell/RefCell/UnsafeCell field shares a cache line with other fields. Detection is recursive, so Option<AtomicU64> and Arc<Mutex<AtomicU64>> are both caught. --strict warns on all multi-field lines regardless.
Structs containing !Send or !Sync types (Rc, Cell, RefCell, raw pointers, lock guards) are automatically suppressed since they can't be shared across threads, making false sharing impossible. Suppressed structs print a note to stderr. Use --no-send-sync-check to disable this and warn on all structs.
Parses structs with syn, then gets exact type sizes and field offsets from cargo +nightly build -Zprint-type-sizes. This resolves all types (custom structs, enums, non-repr(C) layouts, niche-optimized Options) with no guessing.
- All types resolved, including custom and cross-crate types
- Non-repr(C) structs get exact field offsets from the compiler
- Niche optimization (
Option<&T>,Option<NonZeroU64>) handled correctly
The validation/ directory has a controlled experiment that correlates snarf's static warnings with real hardware cache-line contention measured by perf c2c. Two #[repr(C)] structs (one with co-located atomics, one with cache-line padding) are hammered from threads pinned to separate P-cores. The script runs snarf and perf c2c, then compares HITM event counts to snarf's warnings.
cd validation && ./run.sh # requires sudo for perf c2c
repr(packed)not yet supported- Type name collisions: if two modules define a type with the same name (e.g.
a::Configandb::Config), only the first is used (a warning is printed)
snarf — hacker slang: to grab data greedily.
MIT
