Repository navigation
perf: don't hash all-zero chunks - #611
Open
MetehanYurtseven wants to merge 1 commit into
Open
MetehanYurtseven wants to merge 1 commit into
MetehanYurtseven wants to merge 1 commit into
Conversation
Chunks that contain only zeros have a known length: the Rabin hash of a window of zeros is 0, so runs of zeros are cut at the minimum chunk size (the chunk size for the fixed-size chunker). Checking for zeros is far faster than SHA-256, so such chunks now get a precomputed id. restic does the same since 0.15.0 (restic/restic@c147422). Blob ids and the repository format are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Author
|
An end-to-end measurement with a real workload: a raw image backup of a whole Windows disk (100 GiB, about 56 GiB of it free NTFS space, read from a VSS snapshot with free clusters as zeros). The program is a downstream tool built on rustic_core 0.13.0, run with and without this patch cherry-picked onto 0.13.0. Each run went into a fresh local repository. The VM had 4 vCPUs on a Xeon Gold 6254 (no SHA-NI).
The saving (about 4.9 s per GiB of zeros) matches the SHA-256 throughput of that CPU. The repository size is identical, as expected with unchanged blob ids. The gain grows with the share of zeros: for a mostly empty 2 TB disk it would cut a run from hours to minutes. 🤖 Generated with Claude Code |
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
FileArchiver::backup_readercomputes SHA-256 for every chunk, including chunks that contain only zeros. For sparse files and disk images, hashing the zeros dominates the backup time.All-zero chunks have a known length: the Rabin hash of a 64-byte window of zeros is 0 for every polynomial, so runs of zeros are cut at
chunk_min_size(see also #609). With the fixed-size chunker they havechunk_size. This PR computes the id of such a chunk once per backup and uses it for every chunk of that length that is all zeros. Other chunks are hashed as before.restic does the same since 0.15.0 (restic/restic@c147422, restic/restic#3854, discussion in restic/restic#3903).
foldthat the compiler vectorizes: about 64 GiB/s here, compared to 2.4 GiB/s foriter().all().Measurements
4 GiB stream backed up through
Repository::archiveinto a local repository, rustic_core 0.13.0 with this patch applied, Xeon Gold 6254 (no SHA-NI):SHA-256 alone runs at about 227 MiB/s on this CPU, so the zeros were limited by hashing.
Tests
archiver::file_archiver::tests::is_zero_finds_any_nonzero_byteintegration::chunker::test_backup_zerosfor both chunkers: backs up a file with runs of zeros between data, checks withread_data, which compares every blob with its id, and dumps the file again. With a deliberately wrong zero id, both cases fail.cargo fmt --all -- --check,cargo clippy -p rustic_core --all-targets --all-featureswithout warnings.Five snapshot tests (
test_backup_*,test_chunker_params,test_rewrite) fail onmainas well, because the stored snapshots still containerror_count: 0, which is no longer serialized since #561. CI onmain(647d00f) is red for the same reason. This PR doesn't touch them.🤖 Generated with Claude Code