MarCCD: read TIFF frames without memory-mapping, output unchanged

ReadRaw opened each frame with TIFFOpen(path, "r"), which memory-maps the file; on macOS the 32 MB
frame is then paged in under libtiff's copy out of it, and that copy (DumpModeDecode's memmove) was
23% of rugnux's busy CPU samples during 4nwv's image passes. With "rm" libtiff reads the file instead:
memmove 0.9% of the samples. The pixels are the same bytes either way.

Apple M6, 4nwv (the timing benchmark's moved model), alternating runs, two each:
- wall 291.1/285.9 s -> 283.4/284.5 s; system CPU 197/172 s -> 160/160 s
- pre-scan 3.9/3.8 -> 3.4/3.3 s, indexing 8.7/7.5 -> 6.8/6.9 s, metric-symmetry check 5.0/5.1 ->
  2.9/3.0 s; the integration passes, bound by the GPU, within 0.6 s
p.hkl and the placed model are byte-identical. (Reading by strips straight into the frame on top of
this, TIFFReadEncodedStrip: 282.2/273.6 s, not clearly apart from "rm" alone.) On Linux the three
read paths measured the same.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018My7tqt8a4LyKKjP3FhScT
This commit is contained in:
leonarski_fandClaude Opus 5.5 committed 2026-10-18 13:46:16 +02:00
1 parent 14ee27f362
commit 90abe8670e
1 file changed
+3 -1
+3 -1
View File
@@ -306,7 +306,9 @@ Header ReadRaw(const std::string &path, uint16_t *out, size_t capacity) {
throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds,
path + ": image is larger than the buffer given for it");
TIFF *tiff = TIFFOpen(path.c_str(), "r");
// "m": read, not memory-mapped. On macOS a mapped 32 MB frame is paged in under the copy out of it, as
// page faults (a fifth of the image passes' busy CPU samples on 4nwv); the same bits either way.
TIFF *tiff = TIFFOpen(path.c_str(), "rm");
if (tiff == nullptr)
throw JFJochException(JFJochExceptionCategory::TIFFGeneratorError, "Cannot open TIFF " + path);
struct Closer {