CUDA QEM loading and file-cache recheck, 2026-10-23#
The 2048 × 2048 × 192 × 192 acquisition still takes about ten seconds to restore from its 38.333 GB QEM into encoded CUDA residency. A separate copy-only control moves the same byte count into a full-size GPU destination in 1.333 s. The complete loader includes storage reads and authentication; the transfer control excludes both. A one-second complete load was not observed.
Setup and source identity#
Private experiment: 20261023-cuda-qem-cache-recheck. Only acquisition-10 was
tested, at original uint16 precision, with no correction, crop or binning.
The canonical benchmark recreated the QEM and compared all 154,618,822,656
source values exactly, including flagged detector pixels: zero differences.
Temporary QEM storage was removed after the controls.
Hardware: NVIDIA RTX PRO 6000 Blackwell Workstation Edition, 96 GB, with a generation-5 eight-lane GPU link; Intel Core Ultra 7 265K; approximately 125 GiB host RAM. The file was on an ext4 WD_BLACK SN850X 8 TB NVMe, whose negotiated link was 16 GT/s ×4. CUDA runtime 12.9, CuPy 14.2.0, Python 3.14.6.
The existing conversion/verification runner and its interval profiler were
reused with a private cache-control wrapper. The measured source snapshot
fingerprint, which includes scripts and tests, is
25bc5ad212e8476b2c981a218182fb886bc9a48c6a4d2d4e18ee81ee029e08e3.
The acquisition master identity matches the original suite. Loader and envelope
source hashes match the earlier profile and current checkout exactly:
io/qem.py:ca2971acd642f687d4609bb07ddc027e65fc8c3ac1264a77a474bf0c290996cbformats/qem/snapshot.py:71df8125b3dc3d051d3ccea0b23575d8b3d1659dbcfe5531ce32401530b14faa
No production loader or codec implementation changed. These source measurements do not qualify an installed release.
Measurements#
Three uninstrumented QEM reloads took 9.876, 17.055 and 10.214 s. The later
instrumented controls below each retain header and full-body SHA-256 checks,
then synchronize the GPU before stopping the load timer. mincore observes
file-page residency without reading the file. Process IO counters measure
storage reads during each complete load.
QEM load condition |
Load (s) |
File pages resident before (%) |
Storage read during load (GB) |
Read-call active time (s) |
SHA-256 active time (s) |
|---|---|---|---|---|---|
Ordinary repeated load |
10.363 |
43.9 |
37.689 |
10.135 |
6.560 |
Disposable QEM file pages evicted |
10.344 |
0.0 |
38.333 |
9.996 |
6.345 |
After sequential pre-read 1 |
10.452 |
8.6 |
38.102 |
10.257 |
6.369 |
After sequential pre-read 2 |
10.196 |
62.6 |
37.320 |
9.833 |
6.370 |
Only the disposable QEM file received POSIX_FADV_DONTNEED; the measured
resident-page count then reached zero. No global cache was evicted. This controls
OS file pages, not the storage controller’s caches. The sequential pre-reads
took 14.023 and 14.677 s and are excluded from the subsequent loading times.
Read and checksum intervals overlap across four workers; the table reports the union of intervals for each operation. They must not be added to form elapsed load time. Read-call intervals include waiting and copying into pinned staging memory. Host upload-call durations are not GPU transfer durations.
The copy-only control used one repeated 64 MiB pinned host buffer and a full 38.333 GB GPU destination. Three CUDA-event measurements were 1.3330, 1.3331 and 1.3329 s, approximately 28.76 GB/s. It excludes file reads, checksum verification and allocation timing, and does not constitute a QEM loading result or a retained-host-file benchmark.
Interpretation and limits#
The file-page snapshot does not establish that those pages survive until the loader reaches them. Every observed load fetched 97–100% of the QEM size from storage, including after pre-reading. This is strong evidence of a storage-read limit in the observed pipeline. It is not a fully RAM-cached QEM measurement. The precise cause of cache churn was not isolated.
Host anonymous memory was about 62.5–64.0 GiB before and during the controls; background disk verification and desktop services remained active. The GPU was idle before and after the run, but telemetry recorded desktop bursts and two brief other Python GPU processes reaching 7% and 5% SM use. Their identities were not retained after they exited. This was not an exclusive idle-system run; no other processes were stopped. The cooperative GPU lock was held by the benchmark throughout. A separate SSH-session hierarchy check found no finite memory.max or memory.high limit; it is not a capture of the completed process’s now-removed session scope.
QEM avoids re-encoding the acquisition, but it still carries tens of gigabytes that must be read and authenticated. Improving this loading path requires addressing storage/cache behavior and the read/checksum pipeline; GPU compute utilization alone does not measure that bottleneck. The original five-acquisition table retains its matched 10.47 s repeated median. These cache controls are separate measurements, not an optimization or a replacement selected from the fastest trial.