turbine: accelerate 32+32 FEC generation and recovery - #259
Draft
7layermagik wants to merge 11 commits into
Draft
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Reduce CPU overhead in the leader's entry-batching and shred-generation path, and add specialized recovery for exactly one missing data shred in a standard 32+32 FEC set.
Against the current
alpenglow-devhead, the serial producer benchmark processes 50,000 maximum-size transactions in 282 ms instead of 734 ms: 2.60× faster on one pinned Zen 5 CPU. The dev baseline already has incremental batch-size accounting; this comparison measures the remaining benefit against that implementation.Changes
BroadcastSession, eliminating owning shred parsing, payload copies, and root reconstruction.DATA_COMPLETE_SHREDonly at the end of a serialized component spanning multiple FEC sets.ReconstructSome; reduced multi-missing and all-coding implementations remain experiments.The public parsed-shred API remains available. Repair wire format, request signing, peer selection, and scheduler policy are unchanged.
Benchmark against current alpenglow-dev
Baseline:
alpenglow-devat7e4e8af1, verified as the branch head on September 6, 2026. It uses incremental size accounting and a 30,816-byte batch target.Candidate: the PR producer at
a598cd05, using its 61,632-byte default. Commita3b16ebaadds the identical standalone benchmark and results without further production-code changes.Machine and method: AMD Ryzen 7 9700X (Zen 5), Linux amd64, Go 1.26.4,
CGO_ENABLED=0,GOAMD64=v1,GOMAXPROCS=1, pinned to logical CPU 6. Results are medians of five alternating samples per arm, each timing one complete workload. The host was shared, with SMT and boost enabled.Control: same batch target on both versions
With both versions using 30,816-byte batches, the gains remain:
Most of the measured improvement survives at the dev head's one-FEC target. Increasing the PR's target to two FECs adds about 2.1% and 1.4% time reduction in these samples. This does not establish the best target for live latency or pipelined throughput.
Workload and scope
Maximum-size transactions are signed legacy transfers with a memo, exactly 1,232 bytes each. The 512-fixture pool is reused, with structural sanitization, signature verification, and canonical byte round trips performed before timing.
The maximum-size workload uses 16,667 + 16,667 + 16,666 transactions across three slots on both versions to fit dev's slot limits. The harness asserts the 20 MiB-minus-reserved-ending-tick entry-byte bound, the 32,768-data-shred cap, and transaction/batch/packet counts.
For this workload, allocated bytes decrease from 2.129 GB to 708.003 MB, and allocations from 3,844,267 to 974,514. The same-target control produces identical batch and packet counts on both heads. With its larger default, the PR emits slightly fewer packets through denser packing.
Included in timing: entry construction and flushes, serialization, erasure coding, Merkle proofs, shred signing, headers/footers/ending ticks, chained roots, and block-ID bookkeeping. The sink only counts emitted packets.
Excluded: fixture setup, transaction execution, admission signature verification, scheduling/reservation policy, asynchronous shred-worker queueing/overlap, peer routing, UDP, and receiver work. These results measure serial producer CPU-stage work, not whole-validator throughput, executed-block latency, or the wait for a batch to fill.
The comparison uses the two branch heads directly. It does not measure this patch rebased onto dev. Dev's newer slot accounting and asynchronous shred worker must be preserved when integrating these optimizations; the PR's target branch remains
7layer/narya-integration.Standalone benchmark source, exact commits, raw samples, allocation counts, and reproduction steps.
Correctness and validation
Coverage includes:
Recovery derivation and differential-test methodology.
The production changes passed on a clean snapshot, excluding unrelated local experiments:
go test -race -count=1 ./pkg/repair ./pkg/turbine/... ./pkg/costmodel ./pkg/blockprod ./cmd/repair-simgo vet ./pkg/repair ./pkg/blockprod ./pkg/costmodel ./pkg/turbine/... ./cmd/repair-simgit diff --check.The branch-comparison fixtures passed on both Zen 5 binaries. All 30 measured samples passed the count/budget assertions. The added fixture test also passed locally with the race detector, and blockprod vet passed.
A prior whole-repository
go test ./...run was not globally green because of unavailable conformance/genesis fixtures and existing lightbringer/sealevel failures.