Rust / LLVM hot-path experiments
scripts/hotpath_lab.py makes local optimization experiments reproducible without
installing wheels, replacing python/rsloop/_loop.*, switching Python versions,
or rewriting the working tree. It uses committed source snapshots. Uncommitted
Rust changes are deliberately not included. Keep experiment directories under
the ignored target/ tree. Existing output directories are never overwritten.
Run it with the existing project interpreter (.venv/Scripts/python.exe on
Windows, .venv/bin/python on Unix). The harness requires Python 3.10+ and Rust's
matching LLVM tools (rustup component add llvm-tools-preview). The workload
suite uses the project's Python dependencies. TLS workloads additionally need
python scripts/generate_test_tls_certs.py tests/fixtures/tls.
Workflow
In these examples python means the interpreter above. Build commands use a
shared Cargo cache, so do not run builds concurrently, and never benchmark
while compiling, testing, or running another benchmark on the same machine.
python scripts/hotpath_lab.py build --revision HEAD --out target/hotpath-lab/base
python scripts/hotpath_lab.py build --source-artifact target/hotpath-lab/base --instrument --out target/hotpath-lab/instrumented
python scripts/hotpath_lab.py profile --artifact target/hotpath-lab/instrumented --out target/hotpath-lab/training
python scripts/hotpath_lab.py packet --artifact target/hotpath-lab/base --function process_batch --source-file src/vibeio/driver/iocp.rs --profile target/hotpath-lab/training --out target/hotpath-lab/iocp-review
The packet contains original Rust, selected optimized LLVM function definitions,
per-workload execution counts, a review prompt, and build provenance. Use the
packet to propose one falsifiable Rust change, including edge-case tests.
Inspect the preserved assembly in compiler/*.s as well. A function absent from
the IR may have been inlined: select its caller rather than treating absence as
proof that no machine code exists.
opt -passes=verify checks the full emitted IR module before packet creation.
selected.ll is analysis-only: globals, declarations and debug metadata
are omitted; profile weights and referenced attributes are retained. It is not
independently compilable. Neither verification nor an
LLM review establishes semantic equivalence. Raw IR edits, unsafe assumptions,
floating-point reassociation, altered atomic ordering, and changed Python
refcount/exception/cancellation behavior require separate justification.
For compiler-directed optimization, use the same training profile in a PGO build:
python scripts/hotpath_lab.py build --source-artifact target/hotpath-lab/base --pgo target/hotpath-lab/training --out target/hotpath-lab/pgo
python scripts/hotpath_lab.py test --artifact target/hotpath-lab/base --log target/hotpath-lab/base-tests.log
python scripts/hotpath_lab.py test --artifact target/hotpath-lab/pgo --log target/hotpath-lab/pgo-tests.log
python scripts/hotpath_lab.py compare --baseline target/hotpath-lab/base --candidate target/hotpath-lab/pgo --primary tcp_streams --blocks 12 --out target/hotpath-lab/pgo-holdout
For a source candidate, build its commit with --revision <candidate-commit>.
Use a dedicated worktree/branch if you need to preserve ongoing development.
This harness does not apply model output or create commits automatically.
What is controlled
- Artifacts preserve source contents, commit, Python executable/version, compiler versions, exact Cargo command/flags, extension, LLVM IR, assembly, and PDB when emitted. SHA-256 inventories detect changed source/package/compiler outputs.
- Every benchmark child imports the selected artifact first and checks the
actual native extension path and hash. The development installation is not
used.
PYTHONHASHSEED=0, fast streams enabled, and GC disabled during both measured and warmup workloads are explicit harness choices. - PGO builds use an explicit native Cargo
--targetso build scripts and proc macros are not instrumented. Training setsLLVM_PROFILE_FILEonly in workload children, with a new directory per workload and%p-%mshard filenames. Source/toolchain/ABI and merged-profile hash must match for profile use. - Builds and training are separate from timing. Instrumentation counts are
frequencies, not CPU time. Top internal counts may come from a cheap inner
initialization loop. They nominate code for investigation, not CPU hotspots.
Python 3.15's
--nativeflag supplies synthetic boundary markers, not a Rust stack unwinder (Python documentation). PDBs alone cannot turn those markers into Rust function-level CPU samples. plan.jsonis written before measurement: primary workload, thresholds, data sizes, suite, seed, artifact provenance and benchmark hashes. Each block has a fresh baseline process and a fresh candidate process. AB/BA order is balanced and shuffled; workload order is also shuffled between blocks. By default each process performs one full warmup and one measured workload.samples.jsonlis flushed after every process. It includes binary identity, elapsed time, process CPU time, peak RSS, and per-process latency summaries. Warmups are retained but excluded from inference. Peak RSS includes warmups; process CPU time includes event-loop setup/teardown beyond the workload timer.harness/retains the exact runner and benchmark sources for audit (restore their usual repository layout when rerunning them).- Confidence intervals resample paired process log-time ratios, never individual requests. The workload-family intervals use a Bonferroni-adjusted 95% confidence target. Negative percentage changes mean faster. Twelve paired blocks are a minimum, not a promise of adequate statistical power.
- The default gate requires the primary interval to be entirely below -1%, and every workload's interval upper bound to be at most +3%. Any lower bound above +3% rejects the candidate. Short runs (<0.25 s), fewer than 12 blocks, or uncertain bounds cannot pass. The bulk workload is 64–128 MiB per connection, not the old very short 2 MiB transfer.
- Holdout changes concurrency, payloads, task batch size, and work volume.
tls_httpandwebsocket_messagescan be added with--workloadsfor entirely untrained scenario families. Default profile training uses the six core workloads; holdout is the default comparison suite.
Interpreting results honestly
Run an A/A comparison (--baseline and --candidate pointing to the same
artifact) to check harness/host noise. Keep background load stable; use OS CPU
affinity/power controls where appropriate and record them externally. This
harness does not pin CPUs on Windows or control thermal state. Child timeouts
fail the experiment; incomplete results are retained, not promoted.
performance_gate_passed is not automatic acceptance. Require both test
logs, inspect diagnostic latency/RSS regressions, and run a fresh confirmation
experiment. Rust tests use a debug build of the preserved source; Python tests
exercise the exact release extension. The current repository's Python tests are
used for both revisions. No result establishes correctness for all unsafe code.
Bootstrap intervals are approximate. Serial correlation, machine drift, benchmark selection, and repeated searches over candidates can inflate apparent confidence. Do not repeatedly tune against the holdout or stop as soon as an interval looks favorable. Choose the primary and sample budget in advance, retain rejected/inconclusive experiments, and use a new confirmation set for any selected winner. This tool does not automate external LLM calls or upload code.
Earlier target/llm-profiles/*baseline.json / *candidate.json experiments
collected revisions in separate blocks. Pairing those files by run index was
not justified. Some sustained matrix repeats also shared a process; they were
not independent process replications. Treat those speedups and paired intervals
as exploratory, not validated evidence. This harness does not reuse them.
The PGO workflow follows the Rust compiler documentation,
including matching code-generation settings, explicit native targets, and
missing-profile diagnostics. IR/assembly output is provided by rustc's
--emit option.