Skip to content

PERF: Enlarge zlib read buffer in NIfTI reader for NAS performance#1634

Open
imikejackson wants to merge 1 commit into
BlueQuartzSoftware:developfrom
imikejackson:topic/nifti_reader_io_optimization
Open

PERF: Enlarge zlib read buffer in NIfTI reader for NAS performance#1634
imikejackson wants to merge 1 commit into
BlueQuartzSoftware:developfrom
imikejackson:topic/nifti_reader_io_optimization

Conversation

@imikejackson
Copy link
Copy Markdown
Contributor

The NIfTI reader opened files with a bare gzopen(), leaving zlib at its 8 KB default internal buffer. zlib refills from the underlying file in buffer-sized chunks, so a multi-GB .nii.gz triggered hundreds of thousands of small reads. On network attached storage each refill is a latency-bound round-trip, making reads disproportionately slow compared to a local disk.

Call gzbuffer() with a 4 MiB buffer (new shared constant nifti::k_GzReadBufferSize) immediately after every gzopen(), before the first read/seek. This cuts the number of NAS round-trips by ~512x on a 2 GB file while costing only a few MiB of working memory. Larger buffers yield diminishing returns once they exceed the link's bandwidth-delay product and client read-ahead.

The NIfTI reader opened files with a bare gzopen(), leaving zlib at its
8 KB default internal buffer. zlib refills from the underlying file in
buffer-sized chunks, so a multi-GB .nii.gz triggered hundreds of
thousands of small reads. On network attached storage each refill is a
latency-bound round-trip, making reads disproportionately slow compared
to a local disk.

Call gzbuffer() with a 4 MiB buffer (new shared constant
nifti::k_GzReadBufferSize) immediately after every gzopen(), before the
first read/seek. This cuts the number of NAS round-trips by ~512x on a
2 GB file while costing only a few MiB of working memory. Larger buffers
yield diminishing returns once they exceed the link's bandwidth-delay
product and client read-ahead.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@imikejackson imikejackson force-pushed the topic/nifti_reader_io_optimization branch from 17dea01 to 7a3ede2 Compare June 5, 2026 18:50
@imikejackson imikejackson requested a review from JDuffeyBQ June 5, 2026 18:51
* diminishing returns once the buffer exceeds the link's
* bandwidth-delay product and the client's own read-ahead.
*/
inline constexpr usize k_GzReadBufferSize = 1u << 22; // 4 MiB
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be defined to be the type zlib expects

Comment on lines +122 to +124
// Match the voxel reader's enlarged zlib buffer so the (single) header read
// is served by one large refill rather than zlib's 8 KB default. Harmless
// here since only 348 bytes are read, but keeps the two open sites consistent.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should just direct to the variable's comment rather than repeating the rationale everywhere.

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.

2 participants