Add JMH benchmarks comparing read I/O strategies under memory pressure#16279
Add JMH benchmarks comparing read I/O strategies under memory pressure#16279neoremind wants to merge 9 commits into
Conversation
Refactor benchmarks
| MemorySegment slice = mmapSegmentNormal.asSlice(offsets[i], readSize); | ||
| int rc = (int) POSIX_MADVISE.invokeExact(slice, (long) readSize, MADV_WILLNEED); |
There was a problem hiding this comment.
madvise needs a page-aligned start address, so passing the raw random offset here makes it return EINVAL and do nothing — and since rc is discarded, it fails silently. On a c6id.4xlarge strace shows ~5117/5181 of these calls returning -1 EINVAL, so the prefetch never actually runs and the prefetch rows end up identical to plain mmap. The real Directory avoids this because MemorySegmentIndexInput#advise rounds the start down to the page first.
Suggested fix (mirrors what the Directory does):
| MemorySegment slice = mmapSegmentNormal.asSlice(offsets[i], readSize); | |
| int rc = (int) POSIX_MADVISE.invokeExact(slice, (long) readSize, MADV_WILLNEED); | |
| // madvise needs a page-aligned start address, otherwise it returns EINVAL and is a no-op. | |
| long offsetInPage = (mmapSegmentNormal.address() + offsets[i]) % ALIGNMENT; | |
| long aoff = offsets[i] - offsetInPage; | |
| long alen = readSize + offsetInPage; | |
| MemorySegment slice = mmapSegmentNormal.asSlice(aoff, alen); | |
| int rc = (int) POSIX_MADVISE.invokeExact(slice, alen, MADV_WILLNEED); | |
| assert rc == 0 : "posix_madvise failed: " + rc; |
Same change is needed in doMmapMadvRandomBatchedPrefetch (against mmapSegmentMadvRandom). With this, single-threaded mmap+prefetch goes from ~0.15 → ~4.2 ops/ms cold (≈7× pread at T01, ~device saturation). Might be worth asserting on rc at the other madvise call sites too so this can't silently regress again.
Adds JMH benchmarks to compare read I/O strategies in memory constrained scenario, related to #16044.
I/O strategies tested:
NIOFSDirectory)Thread counts: 1, 4, 8, 16.
How to run