> a larger read is generally as fast as multiple smaller one on modern hardware.
Not always if by modern you mean NVMe drives.
One synchronous preadv() for 256 KiB gives the kernel/device one big request but 16 independent asynchronous 16 KiB reads can be serviced concurrently.
So the latter gives the NVMe controller 16 operations it can schedule in parallel.
So depending on the workload and hardware, offsets, filesystem and request sizes that can give you lower aggregate latency or higher throughput.
If you submit 16 contiguous read requests the system will just merge them into one large read request.
Modern SSDs tolerate moderate queue depths very well, but piling on the I/O queue also incurs tail latency jitter unless you're able to ensure the queue depth stays in the moderate range and never goes higher. All else being equal, fewer larger requests is better for I/O latency (though read amplification for the sake of reading more data obviously doesn't help anyone). Though in this scenario, we're mostly comparing the syscall overhead of a single preadv against io_uring bookkeeping for multiple preads, regardless of how you submit the reads they end up being the same operation.
Doesn’t the Linux kernel automatically merge requests for contiguous regions into a single request? I’m not sure 16 read I/Os submitted to io_uring for a contiguous 64kib region will behave differently at the disk level than a single 64kib request. There’s a little bit extra work the kernel has to do to merge the requests but that should be negligible.
In a poorly written micro benchmark test it’s possible the kernel will fail to coalesce all of them because your submissions aren’t visible all at once (ie it starts submitting requests and doesn’t have an opportunity to merge). Whether that actually is possible to happen requires digging a bit more into the Linux kernel source.
I think that’s only true on paper; in practice it’ll be true only when you have competing reads (at a thousand-foot view) and it might be possible to algorithmically bundle a portion thereof. It originally let SCSI controllers attached to spinning rust HDDs optimize physical manipulation of the disk heads to optimized queued reads of data in a “traveling salesman” sort of way, but modern nand flash can only internally read a full page at a time (which may be much greater than even the apparent physical sector size) anyway and with a strictly constant cost regardless of the “physical location” of the data on the non-existent platter. Old drives had optimization constraints like higher sequential read speeds at the outside of the platter (more bytes per physical rotation) and extremely pathological cases for data written to the innermost tracks of the platter. Individual requests were much finer-grained and the latency was much more varied, so a request from app/thread X for as little as 512 bytes from one location could be cheaply piggy-backed on an existing request from app/thread Y to read multiple megabytes from a physically proximate source that would otherwise have seriously delayed or starved the queued waiting read while the outstanding request was serviced.
In fact, one consistently sees higher bulk IO numbers when using physical media that has been formatted with a large sector size compared to the old 512 byte fixed emulated size. You’d routinely see lower latency and higher IOPs with 4kn (HDDs or SSDs) than you would with 512e disks, even with SCSI or AHCI controllers that featured similar pipelining support to today’s NVME controllers (or even if you place a spinning rust HDD behind NVMe today!).
Mostly true but as someone else pointed out it’s still better to issue a single large multi-page contiguous read than the same read broken down into separate requests because the I/O queue isn’t infinite. So both the Linux kernel and the SSD microcontroller still benefit from merging contiguous requests on their end. However, if you issue it correctly at the application level that’s still going to be better in that you’re never going to encounter a situation where you accidentally don’t get the desired coalescing.
> Mostly true but as someone else pointed out it’s still better to issue a single large multi-page contiguous read than the same read broken down into separate requests
A few days ago, my mother asked me to fix her YouTube because she kept getting something telling her to update. I looked at YouTube on her iPhone and saw an autoplaying video ad that displayed an animated fake system style pop-up button, designed to look like an important iPhone OS security update. The ad even showed an animation of the button appearing on the screen, making it look even more like a real system notification.
Like a cat who knows how to teleport so rapidly around the room that he becames a blur. All the while taking into account stuff falling around he knocked down.
> At some point chatting with Fable inevitably leads to it thinking about the security related aspects, tripping the safeguards.
It happens to me all the time with things that have nothing to do with security, Fable spawns a subagent that then adversarially checks the code Fable just wrote and hits guardrails, with zero prompting from me.
I asked Fable to transcribe three short lines of Korean-language text in a small image. It suspected the image might contain song lyrics and refused. Haiku transcribed it with no issue.
> Gross debt to GDP ratio in the US has fallen from 130% in 2021 to under 125% now.
Most of that was inflation, so it hurts U.S. citizens. I mean, you could reduce it even further pretty easily, but I'm not sure you would want to pay $1,000+ for a Big Mac.
reply