Skip to content

perf: cache reconstruction plans and pre-warm on open#21

Merged
XciD merged 3 commits into
mainfrom
perf/reconstruction-cache
Mar 8, 2026
Merged

perf: cache reconstruction plans and pre-warm on open#21
XciD merged 3 commits into
mainfrom
perf/reconstruction-cache

Conversation

@XciD

@XciD XciD commented Mar 7, 2026

Copy link
Copy Markdown
Member

Summary

Two complementary optimizations to eliminate redundant CAS API round-trips for reconstruction plan lookups.

derive_range_response in CachedXetClient

When a range-query (get_reconstruction(hash, Some(range))) misses the cache but the full-file plan (get_reconstruction(hash, None)) is already cached, derive the range response locally by slicing the term list -- no network call. The mutex is released before the derivation so N concurrent pread() calls don't serialize on it.

warm_reconstruction_cache at open()

A fire-and-forget task fetches the full-file reconstruction plan at open() time. By the time the first read() arrives, the plan is typically already in the in-memory cache. Errors are silently dropped (best-effort).

Together these mean that after the first open(), all reconstruction lookups for that file are served from memory.

@github-actions

github-actions Bot commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

Benchmark Results

============================================================
  Benchmark — 50MB
------------------------------------------------------------
  Metric                                 FUSE          NFS
  ------------------------------ ------------ ------------
  Sequential read                    210.8 MB/s     225.8 MB/s
  Sequential re-read                2019.8 MB/s    2299.6 MB/s
  Range read (1MB@25MB)                0.5 ms         0.2 ms
  Random reads (100x4KB avg)           0.0 ms         0.0 ms
  Sequential write (FUSE)           1039.2 MB/s
  Close latency (CAS+Hub)            0.106 s
  Write end-to-end                   323.8 MB/s
  Dedup write                       1024.3 MB/s
  Dedup close latency                0.097 s
  Dedup end-to-end                   342.2 MB/s
============================================================
============================================================
  Benchmark — 200MB
------------------------------------------------------------
  Metric                                 FUSE          NFS
  ------------------------------ ------------ ------------
  Sequential read                   1352.1 MB/s    1206.2 MB/s
  Sequential re-read                2101.1 MB/s    2369.5 MB/s
  Range read (1MB@25MB)                0.2 ms         0.2 ms
  Random reads (100x4KB avg)           0.0 ms         0.0 ms
  Sequential write (FUSE)            974.9 MB/s
  Close latency (CAS+Hub)            0.101 s
  Write end-to-end                   652.3 MB/s
  Dedup write                        959.4 MB/s
  Dedup close latency                0.077 s
  Dedup end-to-end                   701.6 MB/s
============================================================
============================================================
  Benchmark — 500MB
------------------------------------------------------------
  Metric                                 FUSE          NFS
  ------------------------------ ------------ ------------
  Sequential read                   1635.1 MB/s    1253.5 MB/s
  Sequential re-read                2143.0 MB/s    2344.6 MB/s
  Range read (1MB@25MB)                0.2 ms         0.2 ms
  Random reads (100x4KB avg)           0.0 ms         0.0 ms
  Sequential write (FUSE)            966.6 MB/s
  Close latency (CAS+Hub)            0.099 s
  Write end-to-end                   810.7 MB/s
  Dedup write                        956.2 MB/s
  Dedup close latency                0.095 s
  Dedup end-to-end                   809.4 MB/s
============================================================
============================================================
  fio Benchmark Results
------------------------------------------------------------
  Job                        FUSE MB/s   NFS MB/s  FUSE IOPS   NFS IOPS
  ------------------------- ---------- ---------- ---------- ----------
  seq-read-100M                  408.2      332.2                      
  seq-reread-100M               1923.1     1162.8                      
  rand-read-4k-100M                0.3        0.4         88        103
  seq-read-5x10M                 909.1      537.6                      
  rand-read-10x1M                176.7       59.5      45235      15225
  Random Read Latency           FUSE avg      NFS avg
  ------------------------- ------------ ------------
  rand-read-4k-100M           11287.1 us    9740.5 us
  rand-read-10x1M                21.4 us      64.7 us
============================================================

@github-actions

github-actions Bot commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

POSIX Compliance (pjdfstest)

============================================================
  pjdfstest POSIX Compliance Results
------------------------------------------------------------
  Files: 130/130 passed    Tests: 832 total (0 subtests failed)
  Result: PASS
------------------------------------------------------------
  Category               Passed    Total   Status
  -------------------- -------- -------- --------
  chflags                     5        5       OK
  chmod                       8        8       OK
  chown                       6        6       OK
  ftruncate                  13       13       OK
  granular                    5        5       OK
  mkdir                       9        9       OK
  open                       19       19       OK
  posix_fallocate             1        1       OK
  rename                     10       10       OK
  rmdir                      11       11       OK
  symlink                    10       10       OK
  truncate                   13       13       OK
  unlink                     11       11       OK
  utimensat                   9        9       OK
============================================================

@XciD

XciD commented Mar 7, 2026

Copy link
Copy Markdown
Member Author

Benchmark results (EC2 m6i.2xlarge, sequential read FUSE)

File size main PR Delta
50 MB 247 MB/s 276 MB/s +12%
200 MB 893 MB/s 1168 MB/s +31%
500 MB 1431 MB/s 1602 MB/s +12%

Sequential re-reads are identical (~2300 MB/s both sides, page cache bound).

CAS reconstruction calls (PR, total session — 3 files x seq+reread+range+random)

Type Count Description
CAS 3 Network round-trip to CAS server (1 per file, at open)
HIT 306 Served from in-memory cache
DERV 9 Derived client-side from cached plan
Total 318 315/318 = 99% of calls avoid the network

On main, all 318 calls would have been CAS network round-trips.

@XciD XciD force-pushed the perf/reconstruction-cache branch 2 times, most recently from b30ca81 to 98d25dc Compare March 8, 2026 10:05
XciD added 2 commits March 8, 2026 11:13
CachedXetClient now maintains a full-file reconstruction plan cache keyed by
MerkleHash with a 59-minute TTL (presigned URLs expire after 1 hour).

When a range request misses the cache but the full-file plan is cached,
derive_range_response slices the term list locally with no network call.
The lock is released before derivation so concurrent pread() calls do not
serialize on it.

Cache entries store only full-file plans (no per-range entries), which
eliminates stale range responses and keeps the cache small.
warm_reconstruction_cache() fires a background tokio task at open() that
fetches the full-file reconstruction plan from CAS. A watch::Receiver signals
completion; the first read() awaits it only if the warmup is not yet done.

For workloads with any gap between open() and the first read (safetensors
header parsing, Python overhead), the CAS round-trip overlaps with userspace
work and adds zero latency to reads.

FUSE open replies with FOPEN_KEEP_CACHE so the kernel page cache is reused
across re-opens of the same file.
@XciD XciD force-pushed the perf/reconstruction-cache branch from 98d25dc to f8172fe Compare March 8, 2026 10:13
@XciD XciD marked this pull request as ready for review March 8, 2026 10:15
@XciD XciD merged commit d013988 into main Mar 8, 2026
4 checks passed
@XciD XciD deleted the perf/reconstruction-cache branch March 23, 2026 15:47
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