neoremind commented on PR #16279:
URL: https://github.com/apache/lucene/pull/16279#issuecomment-4913504832

   I ran the benchmark across three different hardware profiles to get 
quantitative measurements of how different I/O strategies work under different 
memory pressure. Here are the results. 
   
   ## Platforms
   
   | Platform | CPU | RAM | Storage | 4K random read latency (QD=1) | Saturated 
random read throughput |
   |---|---|---|---|---|---|
   | Mac (M3 Pro) | 12 CPU | 36G | 512G Apple SSD | ~77us | ~840 MB/s |
   | Linux EBS (EC2 c5.4xlarge) | 16 vCPU | 32G | EBS io2, 200G, 20K 
provisioned IOPS | ~334us | ~80 MB/s |
   | Linux NVME (EC2 c6id.4xlarge) | 16 vCPU | 32G | NVME SSD | ~103us | ~1.25 
GB/s |
   
   *The latency and throughput numbers are calculated via `fio` with rand read 
16k + different iodepth/numjobs to find the saturation point.*
   
   ## Benchmark Setup
   
   16k reads (4 pages) x 16 reads/op = 256KB per op.
   
   Throughput (MB/s) = ops/ms × 256k x 1000. For example, with O_DIRECT on 
c6id.4xlarge (Linux NVME SSD), JMH at 16 threads yields 4.9 ops/ms → `4.9 × 
256k x 1000 ≈ 1250 MB/s`, matching the peak random read throughput from `fio`. 
   
   I removed the O_DIRECT results from the table charts below to focus on mmap 
(with `MMapDirectory`), pread (via FFI), and `NIOFSDirectory` (backed by 
FileChannel).
   
   ## Random Read Results
   
   ### CASE 1: Fully warm (all data in page cache)
   
   16G file fits in RAM, pre-warmed with `cat file > /dev/null`.
   <img width="672" height="378" alt="warm-mac" 
src="https://github.com/user-attachments/assets/6aef0f7f-65e5-47a6-b7b0-47544783ef72";
 />
   <img width="662" height="395" alt="warm-linux-ebs" 
src="https://github.com/user-attachments/assets/f4e25b59-3913-40d2-8116-6c99fbf92937";
 />
   <img width="636" height="387" alt="warm-linux-nvme" 
src="https://github.com/user-attachments/assets/b84a59a6-4f81-49f7-8345-399fd21413e6";
 />
   
   - When everything is in RAM, mmap removes syscall overhead, it's pure 
page-table lookup with direct pointer to cached page, also no intermediate 
offheap buffer copy in NIO FileChannel. At T8, mmap is 1.5-2x faster than pread 
and nio FileChannel.
   - Observed that batched WILLNEED prefetch adds ~25–30% overhead since the 
`posix_madvise` syscall is not necessary when pages are already in RAM (see 
[pure mmap w/o using `MMapDirectory` in 
Lucene](https://github.com/apache/lucene/issues/16044#issuecomment-4830551502)).
 But here `MemorySegmentIndexInput#prefetch` uses a power-of-two backoff 
counter to skip prefetch when pages are loaded, this avoids the slightly 
`posix_madvise` penalty for hot data and high IOPS scenarios, so we can see 
there is no difference in performance between all variants of mmap.
   - `NIOFSDirectory` (backed by FileChannel) hits a thread-scaling wall, past 
~4 threads, the `NativeThreadSet` monitor contention bottlenecked performance 
as found in #16044. Pread doesn't suffer from this.
   
   <details>
   <summary>Detailed JMH results (ops/ms, higher is better)</summary>
   
   #### Mac M3 Pro (36G RAM, unified memory, Apple SSD)
   
   | Benchmark | T01 | T04 | T08 | T16 |
   |-----------|-----|-----|-----|-----|
   | mmap (NORMAL) | 77.98 | 224.69 | 285.09 | 296.12 |
   | mmap (RANDOM) | 77.99 | 224.72 | 285.42 | 295.74 |
   | mmap + batchedPrefetch | 77.62 | 223.26 | 284.43 | 294.45 |
   | mmap (RANDOM) + batchedPrefetch | 77.78 | 222.51 | 284.75 | 293.86 |
   | ffiPread | 37.43 | 93.84 | 73.71 | 65.64 |
   | fileChannelNIOFS | 28.05 | 80.32 | 67.77 | 66.43 |
   
   #### Linux c5.4xlarge (16 vCPU, 32G RAM, EBS io2 20K IOPS)
   
   | Benchmark | T01 | T04 | T08 | T16 |
   |-----------|-----|-----|-----|-----|
   | mmap (NORMAL) | 37.46 | 141.00 | 261.55 | 282.78 |
   | mmap (RANDOM) | 36.93 | 141.52 | 261.13 | 282.63 |
   | mmap + batchedPrefetch | 37.00 | 138.04 | 257.00 | 280.10 |
   | mmap (RANDOM) + batchedPrefetch | 36.54 | 138.23 | 256.77 | 280.09 |
   | ffiPread | 22.38 | 77.67 | 134.53 | 185.46 |
   | fileChannelNIOFS | 18.38 | 58.24 | 82.17 | 77.16 |
   | ffiPreadDirectIO (O_DIRECT) | 0.15 | 0.63 | 1.27 | 1.25 |
   
   #### Linux c6id.4xlarge (16 vCPU, 32G RAM, local NVME SSD)
   
   | Benchmark | T01 | T04 | T08 | T16 |
   |-----------|-----|-----|-----|-----|
   | mmap (NORMAL) | 45.16 | 174.57 | 316.09 | 332.71 |
   | mmap (RANDOM) | 46.53 | 173.58 | 316.22 | 332.91 |
   | mmap + batchedPrefetch | 46.22 | 171.98 | 312.48 | 330.43 |
   | mmap (RANDOM) + batchedPrefetch | 45.25 | 171.93 | 312.14 | 330.34 |
   | ffiPread | 31.53 | 114.05 | 204.93 | 261.52 |
   | fileChannelNIOFS | 24.57 | 78.74 | 102.25 | 97.01 |
   | ffiPreadDirectIO (O_DIRECT) | 0.66 | 2.47 | 4.46 | 4.80 |
   
   </details>
   
   ### CASE 2: Memory pressure (working set close to RAM)
   
   32G file barely exceeds RAM, pre-warmed.
   
   <img width="673" height="380" alt="mem-pressure-mac" 
src="https://github.com/user-attachments/assets/b4a3f0ab-9a40-4afe-baa5-90a034651d0f";
 />
   
   <img width="665" height="401" alt="mem-pressure-linux-ebs" 
src="https://github.com/user-attachments/assets/5f7c27c5-5b65-48bb-83c9-77b7a533daac";
 />
   
   <img width="637" height="386" alt="mem-pressure-linux-nvme" 
src="https://github.com/user-attachments/assets/1a3aa38d-e7fe-488b-8d6e-257b9a16377b";
 />
   
   
   - On Mac, mmap is the best strategy.
   - `NIOFSDirectory` thread contention disappears when there are quite amount 
of I/O, since the I/O latency dwarfs the monitor overhead, so threads are no 
longer hot-contending on `NativeThreadSet`.
   - On Linux, pread beats plain mmap at all thread counts with memory pressure 
not matter how big. I think mmap's page-fault path is more expensive than 
pread's syscall on Linux, especially under memory pressure. This paper from 
Andy Pavlo ["Are You Sure You Want to Use MMAP in Your Database Management 
System?"](https://db.cs.cmu.edu/papers/2022/cidr2022-p13-crotty.pdf) argues 
mmap is not the best option for larger-than-memory DBMS workloads if not used 
carefully. It notes InfluxDB, MongoDB, and SingleStore deprecated mmap in their 
latest releases. Section 3.4 (Problem-4: Performance Issues) in the paper 
points to OS page eviction mechanisms that don't scale beyond a few threads for 
larger-than-memory workloads on high-bandwidth storage with bottlenecks like 
page table contention, page eviction overhead, and TLB shootdowns. @mikemccand 
also pointed out the mmap lock bottleneck above. There's also a 
[counter-argument](https://www.scylladb.com/2022/05/19/mmap-is-not-the-best-option-fo
 r-dbms-is-it/) worth reading for balance.
   - This is a case where we still hit hot pages most of the time, but whenever 
we encounter I/O, mmap is not as good as pread, and what's worse, the backoff 
mechanism weakens mmap + prefetch. Batched prefetch should theoretically be the 
most competitive here (as demonstrated in 
[#16044](https://github.com/apache/lucene/issues/16044#issuecomment-4830551502)'s
 benchmarks using customized mmap + prefetch without using `MMapDirectory`), 
but the power-of-two backoff counter causes it to skip most `madvise` calls, so 
its benefit diminishes or gets emptied away. All in all, without prefetch, mmap 
alone is not competitive with pread under memory pressure on Linux, prefetch is 
the silver bullet that makes mmap performant in this scenario.
   
   <details>
   <summary>Detailed JMH results (ops/ms, higher is better)</summary>
   
   #### Mac M3 Pro (36G RAM, unified memory, Apple SSD)
   
   | Benchmark | T01 | T04 | T08 | T16 |
   |-----------|-----|-----|-----|-----|
   | mmap (NORMAL) | 4.76 | 15.73 | 23.50 | 34.65 |
   | mmap (RANDOM) | 4.80 | 15.02 | 24.42 | 33.40 |
   | mmap + batchedPrefetch | 2.54 | 19.52 | 28.09 | 38.22 |
   | mmap (RANDOM) + batchedPrefetch | 5.28 | 16.54 | 23.17 | 32.46 |
   | ffiPread | 2.20 | 7.60 | 12.10 | 16.94 |
   | fileChannelNIOFS | 1.87 | 6.86 | 11.11 | 16.02 |
   
   #### Linux c5.4xlarge (16 vCPU, 32G RAM, EBS io2 20K IOPS)
   
   | Benchmark | T01 | T04 | T08 | T16 |
   |-----------|-----|-----|-----|-----|
   | mmap (NORMAL) | 0.85 | 3.46 | 3.62 | 3.82 |
   | mmap (RANDOM) | 0.50 | 2.03 | 3.38 | 3.35 |
   | mmap + batchedPrefetch | 0.93 | 3.81 | 4.50 | 4.33 |
   | mmap (RANDOM) + batchedPrefetch | 0.50 | 2.00 | 3.33 | 3.38 |
   | ffiPread | 1.48 | 5.15 | 5.48 | 5.12 |
   | fileChannelNIOFS | 1.12 | 4.40 | 4.84 | 4.78 |
   | ffiPreadDirectIO (O_DIRECT) | 0.15 | 0.63 | 1.28 | 1.25 |
   
   #### Linux c6id.4xlarge (16 vCPU, 32G RAM, local NVME SSD)
   
   | Benchmark | T01 | T04 | T08 | T16 |
   |-----------|-----|-----|-----|-----|
   | mmap (NORMAL) | 3.29 | 11.51 | 18.86 | 24.14 |
   | mmap (RANDOM) | 2.14 | 8.45 | 15.29 | 26.36 |
   | mmap + batchedPrefetch | 3.96 | 13.21 | 16.49 | 20.07 |
   | mmap (RANDOM) + batchedPrefetch | 2.25 | 8.58 | 15.52 | 25.87 |
   | ffiPread | 6.04 | 19.05 | 31.47 | 33.87 |
   | fileChannelNIOFS | 4.19 | 15.32 | 26.14 | 29.54 |
   | ffiPreadDirectIO (O_DIRECT) | 0.66 | 2.46 | 4.45 | 4.80 |
   
   </details>
   
   ### CASE 3: Many cold reads (~50% cold reads)
   
   64G file (2x available RAM), ~50% cold reads, pre-warmed.
   
   <img width="672" height="381" alt="half-cold-read-mac" 
src="https://github.com/user-attachments/assets/bc612e43-2f86-4347-9c77-256c46364373";
 />
   <img width="665" height="400" alt="half-cold-read-linux-ebs" 
src="https://github.com/user-attachments/assets/a9191135-0c86-4cce-8f9b-1415432bafd1";
 />
   <img width="637" height="384" alt="half-cold-read-linux-nvme" 
src="https://github.com/user-attachments/assets/9c33dff0-9102-4467-b9b0-d3cf2b65824a";
 />
   
   - mmap + batched prefetch catches up or surpasses pread here. With ~50% of 
pages cold, there's a much higher chance for willneed prefetch to actually 
trigger async I/O operations that deepen iodepth and fill the I/O queue. Even 
at T01, the prefetch benefit is already very obvious, throughput climbs up high 
with just one thread due to batched async I/O.
   - Interestingly, RANDOM is particularly useful under high-concurrency on 
fast NVME, likely because it avoids wasted readahead pages that would otherwise 
be evicted before use. On EBS however, NORMAL wins, the kernel's sequential 
readahead amortizes the high per-request latency of remote block fetches.
   
   <details>
   <summary>Detailed JMH results (ops/ms, higher is better)</summary>
   
   #### Mac M3 Pro (36G RAM, unified memory, Apple SSD)
   
   | Benchmark | T01 | T04 | T08 | T16 |
   |-----------|-----|-----|-----|-----|
   | mmap (NORMAL) | 0.45 | 1.55 | 2.58 | 3.27 |
   | mmap (RANDOM) | 0.45 | 1.97 | 3.17 | 4.28 |
   | mmap + batchedPrefetch | 1.07 | 2.72 | 3.66 | 4.32 |
   | mmap (RANDOM) + batchedPrefetch | 0.98 | 2.83 | 3.84 | 4.61 |
   | ffiPread | 0.58 | 2.53 | 4.16 | 5.53 |
   | fileChannelNIOFS | 0.78 | 2.64 | 4.02 | 5.44 |
   
   #### Linux c5.4xlarge (16 vCPU, 32G RAM, EBS io2 20K IOPS)
   
   | Benchmark | T01 | T04 | T08 | T16 |
   |-----------|-----|-----|-----|-----|
   | mmap (NORMAL) | 0.14 | 0.49 | 0.49 | 0.52 |
   | mmap (RANDOM) | 0.07 | 0.28 | 0.46 | 0.46 |
   | mmap + batchedPrefetch | 0.89 | 1.51 | 1.52 | 1.50 |
   | mmap (RANDOM) + batchedPrefetch | 0.66 | 1.50 | 1.49 | 1.48 |
   | ffiPread | 0.25 | 0.96 | 1.67 | 1.52 |
   | fileChannelNIOFS | 0.22 | 0.88 | 1.42 | 1.38 |
   | ffiPreadDirectIO (O_DIRECT) | 0.15 | 0.62 | 1.27 | 1.25 |
   
   #### Linux c6id.4xlarge (16 vCPU, 32G RAM, local NVME SSD)
   
   | Benchmark | T01 | T04 | T08 | T16 |
   |-----------|-----|-----|-----|-----|
   | mmap (NORMAL) | 0.64 | 1.21 | 1.22 | 1.23 |
   | mmap (RANDOM) | 0.28 | 1.09 | 2.01 | 3.41 |
   | mmap + batchedPrefetch | 3.63 | 5.75 | 6.14 | 6.26 |
   | mmap (RANDOM) + batchedPrefetch | 3.99 | 7.21 | 7.20 | 7.21 |
   | ffiPread | 1.06 | 3.59 | 5.39 | 5.15 |
   | fileChannelNIOFS | 0.88 | 3.23 | 5.15 | 4.98 |
   | ffiPreadDirectIO (O_DIRECT) | 0.66 | 2.47 | 4.45 | 4.80 |
   
   </details>
   
   ### CASE 4: Almost all cold reads
   
   64G file (2x available RAM), clear page cache before each iteration, cold 
start.
   
   <img width="673" height="381" alt="all-cold-mac" 
src="https://github.com/user-attachments/assets/13e0718b-3360-4bf3-a81a-c169077c4f2c";
 />
   <img width="663" height="400" alt="all-cold-linux-ebs" 
src="https://github.com/user-attachments/assets/a053bc8f-8fd9-46a6-8513-2e6a2ec0f3e7";
 />
   <img width="639" height="389" alt="all-cold-linux-nvme" 
src="https://github.com/user-attachments/assets/c66bb3fe-b5da-4b79-b70a-17cce0fc8009";
 />
   
   
   - Same story as Case 3, but the gap widens since mmap + batchedPrefetch wins 
more on both EBS and NVME.
   - The current `MMapDirectory` + prefetch backoff strategy is well-designed 
for the fully warm and almost all code reads, but when data is mix of warm and 
cold, the backoff counter ramps up from hot-page hits and skips the batched 
`WILLNEED` hints diminishing the effect. So whether to enable prefetch all the 
time is not one-size-fits-all, it depends on query pattern like warm/cold read 
ratio and what if warm loads are accessed first. This aligns with my finding in 
https://github.com/apache/lucene/pull/16145#issuecomment-4594402925.
   
   <details>
   <summary>Detailed JMH results (ops/ms, higher is better)</summary>
   
   #### Mac M3 Pro (36G RAM, unified memory, Apple SSD)
   
   | Benchmark | T01 | T04 | T08 | T16 |
   |-----------|-----|-----|-----|-----|
   | mmap (NORMAL) | 0.30 | 0.67 | 1.97 | 2.29 |
   | mmap (RANDOM) | 0.19 | 0.98 | 1.84 | 2.85 |
   | mmap + batchedPrefetch | 0.40 | 1.49 | 2.56 | 3.45 |
   | mmap (RANDOM) + batchedPrefetch | 0.42 | 1.51 | 2.54 | 3.38 |
   | ffiPread | 0.41 | 1.58 | 2.61 | 3.38 |
   | fileChannelNIOFS | 0.38 | 1.55 | 2.56 | 3.41 |
   | ffiPreadDirectIO (F_NOCACHE) | 0.44 | 1.97 | 3.56 | 5.68 |
   
   #### Linux c5.4xlarge (16 vCPU, 32G RAM, EBS io2 20K IOPS)
   
   | Benchmark | T01 | T04 | T08 | T16 |
   |-----------|-----|-----|-----|-----|
   | mmap (NORMAL) | 0.08 | 0.33 | 0.32 | 0.33 |
   | mmap (RANDOM) | 0.04 | 0.16 | 0.26 | 0.26 |
   | mmap + batchedPrefetch | 1.36 | 1.35 | 1.35 | 1.38 |
   | mmap (RANDOM) + batchedPrefetch | 1.34 | 1.35 | 1.35 | 1.37 |
   | ffiPread | 0.14 | 0.57 | 1.15 | 1.36 |
   | fileChannelNIOFS | 0.14 | 0.58 | 1.15 | 1.36 |
   | ffiPreadDirectIO (O_DIRECT) | 0.16 | 0.63 | 1.27 | 1.28 |
   
   #### Linux c6id.4xlarge (16 vCPU, 32G RAM, local NVME SSD)
   
   | Benchmark | T01 | T04 | T08 | T16 |
   |-----------|-----|-----|-----|-----|
   | mmap (NORMAL) | 0.45 | 0.87 | 0.87 | 0.94 |
   | mmap (RANDOM) | 0.16 | 0.62 | 1.18 | 2.11 |
   | mmap + batchedPrefetch | 4.60 | 6.07 | 6.08 | 6.17 |
   | mmap (RANDOM) + batchedPrefetch | 4.53 | 6.26 | 6.26 | 6.64 |
   | ffiPread | 0.63 | 2.35 | 4.24 | 4.65 |
   | fileChannelNIOFS | 0.62 | 2.32 | 4.20 | 4.65 |
   | ffiPreadDirectIO (O_DIRECT) | 0.66 | 2.47 | 4.45 | 4.95 |
   
   </details>
   
   ## Sequential Read Results
   
   64G file, page cache dropped before each iteration. 128 sequential reads per 
op at varying read sizes (16KB, 64KB, 128KB).
   
   Look at Linux, mmap (NORMAL) with default kernel readahead performs well 
across the board for sequential access. mmap (RANDOM) + batchedPrefetch is as 
good as mmap (NORMAL) with readahead, again, the power-of-two backoff 
diminishes the effect.
   
   <img width="533" height="279" alt="seq-mac" 
src="https://github.com/user-attachments/assets/4c2d5ca8-758e-42cb-83ac-e23a90701397";
 />
   <img width="532" height="278" alt="seq-linux-ebs" 
src="https://github.com/user-attachments/assets/45027548-2c07-4faf-99db-e6bf3a3ace9a";
 />
   <img width="533" height="277" alt="seq-linux-nvme" 
src="https://github.com/user-attachments/assets/d992edf8-7174-4ff2-9087-daa5a927fdc0";
 />
   
   <details>
   <summary>Detailed JMH results (ops/ms, higher is better)</summary>
   
   #### Mac M3 Pro (36G RAM, unified memory, Apple SSD)
   
   | Benchmark | 16KB | 64KB | 128KB |
   |-----------|------|------|-------|
   | mmap (NORMAL) | 4.032 | 0.993 | 0.503 |
   | mmap (SEQUENTIAL) | 2.292 | 0.601 | 0.288 |
   | mmap (RANDOM) | 1.839 | 0.452 | 0.231 |
   | mmap (RANDOM) + batchedPrefetch | 5.391 | 1.546 | 0.871 |
   | ffiPread | 2.009 | 0.661 | 0.577 |
   | fileChannelNIOFS | 2.123 | 0.510 | 0.261 |
   | ffiPreadDirectIO (F_NOCACHE) | 0.860 | 0.218 | 0.152 |
   
   #### Linux c5.4xlarge (16 vCPU, 32G RAM, EBS io2 20K IOPS)
   
   | Benchmark | 16KB | 64KB | 128KB |
   |-----------|------|------|-------|
   | mmap (NORMAL) | 2.223 | 0.601 | 0.272 |
   | mmap (SEQUENTIAL) | 2.236 | 0.563 | 0.281 |
   | mmap (RANDOM) | 0.101 | 0.024 | 0.011 |
   | mmap (RANDOM) + batchedPrefetch | 2.205 | 1.136 | 0.565 |
   | ffiPread | 1.922 | 0.553 | 0.275 |
   | fileChannelNIOFS | 2.276 | 0.491 | 0.266 |
   | ffiPreadDirectIO (O_DIRECT) | 0.163 | 0.072 | 0.035 |
   
   #### Linux c6id.4xlarge (16 vCPU, 32G RAM, local NVME SSD)
   
   | Benchmark | 16KB | 64KB | 128KB |
   |-----------|------|------|-------|
   | mmap (NORMAL) | 9.437 | 2.374 | 1.189 |
   | mmap (SEQUENTIAL) | 7.405 | 1.848 | 0.925 |
   | mmap (RANDOM) | 0.722 | 0.180 | 0.090 |
   | mmap (RANDOM) + batchedPrefetch | 9.816 | 2.454 | 1.224 |
   | ffiPread | 9.694 | 2.388 | 1.200 |
   | fileChannelNIOFS | 11.027 | 2.720 | 1.386 |
   | ffiPreadDirectIO (O_DIRECT) | 0.703 | 0.153 | 0.076 |
   
   </details>
   
   ## fio vs. JMH benchmarks
   
   I cross-validated against fio on c6id.4xlarge (NVME). The JMH numbers match 
fio within about 4% overhead (like JVM indirections, jmh blackhole?):
   
   - Sequential 1MB reads: JMH pread/NIOFS/mmap 12.01K IOPS vs. fio 
(sync/psync/libaio/mmap) 12.5K IOPS, both saturate disk bandwidth
   
   <details>
   <summary>Command used</summary>
   
   ```
   sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
   java -jar 
lucene/benchmark-jmh/build/benchmarks/lucene-benchmark-jmh-11.0.0-SNAPSHOT.jar 
"SequentialReadIOBenchmark\.(fileChannelNIOFS)" \
     -jvmArgs "--enable-native-access=ALL-UNNAMED -Xms2g -Xmx2g 
-Dbench.file=/mnt/local/bench-64G.dat -Dbench.fileSizeMB=65536" \
     -p readSize=1048576 -p readsPerOp=1 -r 30
   
   sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
   java -jar 
lucene/benchmark-jmh/build/benchmarks/lucene-benchmark-jmh-11.0.0-SNAPSHOT.jar 
"SequentialReadIOBenchmark\.(ffiPread)" \
     -jvmArgs "--enable-native-access=ALL-UNNAMED -Xms2g -Xmx2g 
-Dbench.file=/mnt/local/bench-64G.dat -Dbench.fileSizeMB=65536" \
     -p readSize=1048576 -p readsPerOp=1 -r 30
   
   sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
   java -jar 
lucene/benchmark-jmh/build/benchmarks/lucene-benchmark-jmh-11.0.0-SNAPSHOT.jar 
"SequentialReadIOBenchmark\.(mmap)" \
     -jvmArgs "--enable-native-access=ALL-UNNAMED -Xms2g -Xmx2g 
-Dbench.file=/mnt/local/bench-64G.dat -Dbench.fileSizeMB=65536" \
     -p readSize=1048576 -p readsPerOp=1 -r 30
   
   fio --name=seqread \
   --rw=read \
   --bs=1m \
   --size=64g \
   --numjobs=1 \
   --ioengine=psync \
   --direct=1 \
   --runtime=30 \
   --time_based \
   --group_reporting \
   --filename=/mnt/local/bench-64G.dat
   
   fio --name=seqread \
   --rw=read \
   --bs=1m \
   --size=64g \
   --numjobs=1 \
   --ioengine=mmap \
   --direct=1 \
   --runtime=30 \
   --time_based \
   --group_reporting \
   --filename=/mnt/local/bench-64G.dat
   
   fio --name=seqread \
   --rw=read \
   --bs=1m \
   --size=64g \
   --numjobs=1 \
   --ioengine=libaio \
   --direct=1 \
   --runtime=30 \
   --time_based \
   --group_reporting \
   --filename=/mnt/local/bench-64G.dat
   ```
   </details>
   
   - Random 16KB reads (4 threads, QD=1): JMH pread 40.5K IOPS vs. fio libaio 
42.8K IOPS
   
   <details>
   <summary>Command used</summary>
   
   ```
   sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
   java -jar 
lucene/benchmark-jmh/build/benchmarks/lucene-benchmark-jmh-11.0.0-SNAPSHOT.jar 
"RandomReadIOBenchmark\.(ffiPread_T04)" \
     -jvmArgs "--enable-native-access=ALL-UNNAMED -Xms2g -Xmx2g 
-Dbench.file=/mnt/local/bench-64G.dat -Dbench.fileSizeMB=65536" \
     -p readSize=16384 -p readsPerOp=1 -f 1 -wi 1 -w 3 -i 1 -r 30
   
   ## no direct set, so some page caches hit
   
   fio --name=randread \
   --rw=randread \
   --bs=16k \
   --size=64g \
   --iodepth=x \
   --numjobs=4 \
   --ioengine=libaio \
   --runtime=30 \
   --time_based \
   --group_reporting \
   --filename=/mnt/local/bench-64G.dat
   ```
   
   </details>
   
   - Random 16KB with mmap: JMH and fio mmap (QD=1) can both achieve 12K IOPS
   
   <details>
   <summary>Command used</summary>
   
   ```
   
   sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
   java -jar 
lucene/benchmark-jmh/build/benchmarks/lucene-benchmark-jmh-11.0.0-SNAPSHOT.jar 
"RandomReadIOBenchmark\.(mmap_T04)" \
     -jvmArgs "--enable-native-access=ALL-UNNAMED -Xms2g -Xmx2g 
-Dbench.file=/mnt/local/bench-64G.dat -Dbench.fileSizeMB=65536" \
     -p readSize=16384 -p readsPerOp=1 -f 1 -wi 1 -w 3 -i 1 -r 10
     
   fio --name=randread \
   --rw=randread \
   --bs=16k \
   --size=64g \
   --iodepth=1 \
   --numjobs=4 \
   --ioengine=mmap \
   --runtime=30 \
   --time_based \
   --group_reporting \
   --filename=/mnt/local/bench-64G.dat
   
   ```
   </details>
   
   - Random 16KB with mmap: JMH (mmap + batched prefetch) and fio libaio 
(QD=16, numjobs=4) can both saturate I/O with 80K IOPS and 1.25G throughput.
   
   <details>
   <summary>Command used</summary>
   
   ```
   # convert result by 5.0 ops/ms x 16 ops x 1000 = 80K IOPS
   # JMH can go even higher if we extend running time from 10 seconds to more 
because of more hot page cache hit
   sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
   java -jar 
lucene/benchmark-jmh/build/benchmarks/lucene-benchmark-jmh-11.0.0-SNAPSHOT.jar 
"RandomReadIOBenchmark\.(mmapRandom_T04)" \
     -jvmArgs "--enable-native-access=ALL-UNNAMED -Xms2g -Xmx2g 
-Dbench.file=/mnt/local/bench-64G.dat -Dbench.fileSizeMB=65536" \
     -p readSize=16384 -p readsPerOp=16 -f 1 -wi 1 -w 1 -i 1 -r 10
   
   fio --name=randread \
   --rw=randread \
   --bs=16k \
   --size=64g \
   --iodepth=16 \
   --numjobs=4 \
   --ioengine=libaio \
   --direct=1 \
   --runtime=30 \
   --time_based \
   --group_reporting \
   --filename=/mnt/local/bench-64G.dat
   ```
   
   </details>
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to