← Back to context

Comment by vlovich123

5 days ago

That’s not the only case. A read call makes your thread unable to do anything for the duration of the read. Io_uring lets that same thread continue to handle other requests which themselves might generate more I/O that gets amortized.

The fair comparison isn’t 1 syscall on a single thread processing 1 task against io_uring. That would be insane because you clearly don’t have any performance requirements in such a workload already.

The closest realistic equivalent would be using Tokio’s spawn_blocking to do that 1 syscall vs doing that syscall in io_uring. It’s probably still more efficient if your benchmark literally is the cost of 1 syscall at a time but not by as much and io_uring in poll mode doesn’t even enter the kernel so it can actually outperform the syscall offloaded to a background thread (even though yes under the hood it’s the same kernel code).

DBMS workloads aren't asynchronous like that though. There generally isn't anything you can do while you wait for the buffer pool to execute a read, since what you want to do next depends on the data being read.

  • Of course it is and there is. Generally DBMSs are not handling 1 request at a time. Indeed such a DBMS wouldn’t be taken seriously. All of them support running run multiple requests concurrently. This is where io_uring is really important because it lets one thread schedule I/O to satisfy one request and resume processing a different request.

    Requests are also not I/O bound - you have a mix of CPU work to figure out where to issue the I/O and to manage the cache buffers on completion and read whatever information you need from the buffer pulled in.

    But sure, if all your DBMS is going to be doing is one point lookup at a time then there’s no benefit. But even non trivial SQL queries will surprise you because you can get complicated IO famous (eg checking the index which then tells you multiple blocks to look through which you can do concurrently).

    TLDR: unless your DBMS is ass slow, pread isn’t sufficient to get good throughput. And at that point it’s irrelevant if a single preadv is faster than io_uring.