Live data from Hacker News

A programmer-friendly I/O abstraction over io_uring and kqueue

tigerbeetle.com

11–20 of 34 posts

Re: A programmer-friendly I/O abstraction over io_uring and kqueue

#11
post #4

Earlier quoted context omitted.

> Is there any attempt to reorder IO events such that writes (and maybe reads) operate in as contiguous of a manner as possible? Something like a disk elevator at a higher level of the stack?

Yeah, even tweaking kernel IO scheduling would probably be sufficient. It'll depend on spinning rust vs SSDs though.

Yes, our thinking here was that for SSD or NVMe sometimes the cost of scheduling is not worth it, and "noop" can be a good choice, since the device is already so fast relative to the cost of the CPU and memory access required to schedule.

As far as we understand w.r.t. mechanical sympathy for flash, what counts most is either a large bulk I/O that the device can internally parallelize, or else sufficiently parallel smaller I/Os.

Then, being sector-aligned to avoid the kernel from having to fixup alignment with a memcpy—also, we're using Direct I/O so we have to—and especially trying to issue writes all with similar “Time of Death”. For example, if you're writing out the blocks for a new LSM table on disk, then it is in fact good to keep these close together, since it's likely they'll be compacted again and reclaimed at the same time in future.

This brings us back to scheduling... :)

Re: A programmer-friendly I/O abstraction over io_uring and kqueue

#12

Hey folks! Phil from TigerBeetle here. Happy to answer questions or pull in King when I cannot. :)

Is there a reason why you’re not using libdispatch on darwin and instead using kqueue directly?

King from TigerBeetle here.

One of the reasons is that libdispatch's I/O functions introduce extra dynamic allocations for internal queueing via `dispatch_async` ([0],[1],[2]) and from an API perspective of realloc-ing [3] an internally owned [4] buffer.

TigerBeetle, on the other hand, statically allocates all I/O buffers upfront [5], treats these buffers as intrusively-provided typed data [6] (no growing/owned buffers), and does internal queueing without synchronization or dynamic allocation [7].

[0]: https://github.com/apple/swift-corelibs-libdispatch/blob/469...

[1]: https://github.com/apple/swift-corelibs-libdispatch/blob/469...

[2]: https://github.com/apple/swift-corelibs-libdispatch/blob/469...

[3]: https://github.com/apple/swift-corelibs-libdispatch/blob/469...

[4]: https://developer.apple.com/documentation/dispatch/1388933-d...

[5]: https://tigerbeetle.com/blog/a-database-without-dynamic-memo...

[6]: https://github.com/tigerbeetledb/tigerbeetle/blob/d15acc663f...

[7]: https://github.com/tigerbeetledb/tigerbeetle/d15acc663f8882c...

Re: A programmer-friendly I/O abstraction over io_uring and kqueue

#13
post #7

Earlier quoted context omitted.

Can this benefit BSDs?

I think FreeBSD invented kqueue and from a quick search it looks like OpenBSD and NetBSD also adopted it. We've seen at least one person slightly tweak TigerBeetle to run on FreeBSD already through the darwin code paths.

> We've seen at least one person slightly tweak TigerBeetle to run on FreeBSD already through the darwin code paths.

I'm part of that sample set! Was quite surprised how easy it was to get it up and running on FreeBSD. Benchmarking on tmpfs on both, it even had a ~10% lead on Linux.

(Of course, that's not exactly the intended use case, so don't pay too much attention to that number!)

Re: A programmer-friendly I/O abstraction over io_uring and kqueue

#14
"The good news is that Windows also has a completion based system similar to io_uring but without batching, called IOCP"

fwiw IOCP in NT predates the similar mechanisms in Linux by at least a decade (and the VMS QIO scheme upon which it was in turn based is even older). As I understand it the reason Unix(1) (and then Linux) did not have efficient network I/O kernel interfaces until relatively recently was due to fear of patent litigation from MS.

(1) except for AIX, possibly due to IBM being less concerned about MS patents in this area.

Re: A programmer-friendly I/O abstraction over io_uring and kqueue

#15
post #12

Earlier quoted context omitted.

Is there a reason why you’re not using libdispatch on darwin and instead using kqueue directly?

King from TigerBeetle here. One of the reasons is that libdispatch's I/O functions introduce extra dynamic allocations for internal queueing via `dispatch_async` ([0],[1],[2]) and from an API perspective of realloc-ing [3] an internally owned [4] buffer. TigerBeetle, on the other hand, statically allocates all I/O buffers upfront [5], treats these buffers as intrusively-provided typed data [6] (no growing/owned buffe…

Thank you! I was indeed looking for the technical details!

Re: A programmer-friendly I/O abstraction over io_uring and kqueue

#16

"The good news is that Windows also has a completion based system similar to io_uring but without batching, called IOCP" fwiw IOCP in NT predates the similar mechanisms in Linux by at least a decade (and the VMS QIO scheme upon which it was in turn based is even older). As I understand it the reason Unix(1) (and then Linux) did not have efficient network I/O kernel interfaces until relatively recently was due to fear…

IOCP was missing a rather obvious feature until recently: disassociating a handle from an IOCP:

https://stackoverflow.com/questions/30688028/un-associate-so...

Re: A programmer-friendly I/O abstraction over io_uring and kqueue

#17

"The good news is that Windows also has a completion based system similar to io_uring but without batching, called IOCP" fwiw IOCP in NT predates the similar mechanisms in Linux by at least a decade (and the VMS QIO scheme upon which it was in turn based is even older). As I understand it the reason Unix(1) (and then Linux) did not have efficient network I/O kernel interfaces until relatively recently was due to fear…

TL;DR - Async I/O wasn't included in Unices because it's hard & complex and unices are about keeping to the simple till you can no longer lie about it being painless.

Considering that Windows NT's IOCP is very close to direct copy of VMS QIO mechanism (and even more underneath in officially undocumented boundary layer between user space and kernel space), I don't think it's a case of patents.

UNIX was just always against asynchronous I/O, back from the start - asynchronous I/O schemes were known and used as early as original UNIX, and going with fully synchronous model was explicit design choice at Bell Labs.

When asynchronous I/O turned out to be important enough to include after all, there was no common enough interface to handle it and everyone was using select() and poll() out of lack of anything better for the most obvious use cases of AIO (networking). Meanwhile properly implementing asynchronous I/O can be non-trivial - QIO never ran truly multithreaded from the PoV of client program, for example (NT focused on making sure async worked from start).

Re: A programmer-friendly I/O abstraction over io_uring and kqueue

#18
post #17

"The good news is that Windows also has a completion based system similar to io_uring but without batching, called IOCP" fwiw IOCP in NT predates the similar mechanisms in Linux by at least a decade (and the VMS QIO scheme upon which it was in turn based is even older). As I understand it the reason Unix(1) (and then Linux) did not have efficient network I/O kernel interfaces until relatively recently was due to fear…

TL;DR - Async I/O wasn't included in Unices because it's hard & complex and unices are about keeping to the simple till you can no longer lie about it being painless. Considering that Windows NT's IOCP is very close to direct copy of VMS QIO mechanism (and even more underneath in officially undocumented boundary layer between user space and kernel space), I don't think it's a case of patents. UNIX was just always aga…

> Considering that Windows NT's IOCP is very close to direct copy of VMS QIO mechanism

Microsoft hired the main architect of VMS, Dave Cutler, away from DEC to design Windows NT - so this shouldn’t be a surprise.

https://news.ycombinator.com/item?id=32602132

Re: A programmer-friendly I/O abstraction over io_uring and kqueue

#19

Hey folks! Phil from TigerBeetle here. Happy to answer questions or pull in King when I cannot. :)

It'd be super cool to be able to use this as a standalone library — do you have an estimate as to how much work / time it might take to split this out?

Re: A programmer-friendly I/O abstraction over io_uring and kqueue

#20

"The good news is that Windows also has a completion based system similar to io_uring but without batching, called IOCP" fwiw IOCP in NT predates the similar mechanisms in Linux by at least a decade (and the VMS QIO scheme upon which it was in turn based is even older). As I understand it the reason Unix(1) (and then Linux) did not have efficient network I/O kernel interfaces until relatively recently was due to fear…

Windows has I/O rings now too. https://learn.microsoft.com/en-us/windows/win32/api/ioringap...
Post reply on HN