[HN Gopher] io_uring support for libuv - 8x increase in throughput
       ___________________________________________________________________
        
       io_uring support for libuv - 8x increase in throughput
        
       Author : truth_seeker
       Score  : 103 points
       Date   : 2023-05-28 17:51 UTC (5 hours ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | dan-robertson wrote:
       | The 8x speedup seems to come from a microbenchmark that requires
       | no real async work from the kernel (so I think is mostly going to
       | be stressing out context switches and the threadpool data
       | structures in the non-uring case) but I'm still excited about the
       | improvements to async io from io_uring.
       | 
       | Question I've not figured out yet: how can one trace io_uring
       | operations? The api seems kinda incompatible with ptrace (which
       | is what strace uses) but maybe there is an appropriate place to
       | attach an ebpf? Or maybe users of io_uring will have to add their
       | own tracing?
        
         | znpy wrote:
         | > The 8x speedup seems to come from a microbenchmark that
         | requires no real async work from the kernel
         | 
         | which is nice because you can measure the actual library
         | overhead without the noise from real kernel work.
        
           | theLiminator wrote:
           | Yeah, might have been better to reword it as a "8x reduction
           | in overhead" or something to make it more clear that it's
           | highly unlikely you'll see this in real workloads.
        
         | truth_seeker wrote:
         | Observability on how kernel handles io_uring request -
         | https://github.com/axboe/liburing/issues/467
        
         | tptacek wrote:
         | Yes: the title of this post should be "libuv: introduce
         | io_uring support", not what it is now.
        
       | xiphias2 wrote:
       | Maybe this is an arrogant question, but why adding asyncio to
       | these libraries in general in all OSs is slow?
       | 
       | I would think that writing the kernel part would be the hardest,
       | but it's usually the event loop implementations that don't use
       | what the Windows/MacOS/Linux kenels offer.
        
         | woooooo wrote:
         | Liburing is pretty recent, and it started with a really limited
         | set of syscalls it supports.
         | 
         | Everyone is adopting it pretty quickly, actually.
        
         | rwmj wrote:
         | We tried to add io_uring support to libnbd (and indeed still
         | hope to do so). There's a bit of an "impedance mismatch"
         | between existing event-driven code and io_uring, not
         | impossible, but also not completely easy to just convert code.
         | Especially when you want to keep the non-io_uring code working
         | (for old Linux, BSD etc).
         | 
         | To give an example, libnbd does a lot of send and recv system
         | calls interleaved, for sending requests and receiving replies,
         | with a complicated state machine to keep track of when we would
         | block. It's still not obvious how to convert this to an
         | io_uring style where you have to add the send/recv requests to
         | the submission queue and then separately pick up the responses
         | from the completion queue. It's a particular problem dealing
         | with possible errors and keeping the API the same (if you just
         | call exit when you hit any error, it's a lot easier).
         | 
         | If you're writing all new code then io_uring is a great choice.
        
           | xiphias2 wrote:
           | I was playing with Tokio / Rust on MacOS and hit an about max
           | 500k requests / second limit where the CPU was mostly doing
           | send / recieve calls, not using MacOS asyncio system calls.
           | 
           | I know it's a different library, and asyncio is not as
           | flexible as io_uring, but at least batching send / recv calls
           | from different sockets would be good to be able to do.
        
       | fanf2 wrote:
       | My employer, ISC, sponsored this work because we use libuv in
       | BIND9 and we would like everyone to benefit more from the new
       | io_uring hotness.
        
         | 0x000xca0xfe wrote:
         | Awesome, do you have any data for performance or RAM usage of
         | epoll vs. io_uring in a real-world scenario for BIND9?
        
           | fanf2 wrote:
           | Not yet :-)
        
       | fit2rule wrote:
       | [dead]
        
       | rektide wrote:
       | And this is after node.js v20 already had some very impressive
       | more compute-centric wins! https://blog.rafaelgss.dev/state-of-
       | nodejs-performance-2023
        
         | gavinray wrote:
         | Very excited for the performance implications for Node in
         | general. Node is going to be very speedy in v21.
        
       | ithinkso wrote:
       | It's the same 'for' in the title that I don't understand in the
       | 'Windows subsystem for Linux'. English is not my native language
       | but it is only recently that I started to notice this usage of
       | for. Has it always been used like this?
       | 
       | Github post does it normally: 'Add io_uring support for several
       | asynchronous file operations:'
        
         | quietbritishjim wrote:
         | Unless the title has been changed since your comment, it's not
         | the same "for" as "Windows Services for Linux". In that, the
         | first thing now has been modified to support the second thing.
         | In "io_ring support for libuv", the second thing has been
         | modified so it works with the first thing.
         | 
         | For what it's worth, I'm a native English speaker and I agree
         | they both sound the wrong way round to me! But I can convince
         | myself that they do also make sense the way round they were
         | intended.
        
         | inktype wrote:
         | Unfortunately, "x y for z" can be parsed in multiple ways that
         | result in opposite meanings.
         | 
         | Explaining with examples:
         | 
         | * [io_uring support] [for libuv]: "libuv has io_uring support"
         | 
         | * [io_uring] [support for libuv]: "io_uring has support for
         | libuv"
         | 
         | * [Windows subsystem] [for Linux]: "Linux has a Windows
         | subsystem"
         | 
         | * [Windows] [subsystem for Linux]: "Windows has a subsystem for
         | Linux"
         | 
         | [x] [y for z] / "x has y for z" is much more common.
        
         | [deleted]
        
         | leni536 wrote:
         | I think it's just that "Windows X for Y" where Y is a possibly
         | trademarked entity works better for Microsoft in general. Maybe
         | it wasn't risky for Linux, but if they ever want an other
         | "Windows subsystem for Z", where Z is a trademarked name, then
         | this puts them in the clear.
        
         | dan-robertson wrote:
         | I guess the first thing to note is that 'for' is the kind of
         | old common word that tends to have a lot of meanings.
         | Nevertheless:
         | 
         | 1. I think they are not the same senses. In 'windows subsystem
         | for Linux', the word means 'having as a function' like in the
         | phrase 'spanner for 1/4 inch hex bolts'.
         | 
         | 2. I think the sense in the title is more like 'to the benefit
         | of' (or perhaps 'affecting' or 'having the reason') like 'lunch
         | for employees' or 'supports for the lintel'
         | 
         | 3. I checked a couple of dictionaries and they had the sense
         | but definitions for words like these can be pretty hard to read
         | even for a native speaker.
        
         | gnfargbl wrote:
         | "X for Y" isn't a new thing ("Windows for Workgroups", 1993)
         | but I think the phrasing is possibly more common in the tech
         | world than outside it.
        
           | kzrdude wrote:
           | What about "German for Engineers"? is that the same "for"?
           | I'm thinking of a ficticious language course for engineers..
        
             | wongarsu wrote:
             | While "Engineers for Ukraine" is probably about building
             | drones and shipping them to the Russian border region.
        
           | ithinkso wrote:
           | That's not it, X for Y sounds completely normal as in 'food
           | for kids' or something. But I have read the title as if
           | io_uring added support for libuv.
        
             | refulgentis wrote:
             | I'm a native speaker, read it wrong at first, and had to
             | think step by step. "well, libuv is a JS-related library,
             | io_ring is an OS level concept, so its probably a change to
             | libuv", and still had uncertainty and opened GitHub to
             | double check.
             | 
             | You make a really good point I never heard before: X for Y
             | is an ambiguous construct with two names referring to the
             | same class of object, without an obvious relationship. Ex.
             | Barack for Don is easy, but only if you know American
             | politics, a reference to "a predecessor". But "Jon for
             | Mary" is inscrutable.
        
             | wongarsu wrote:
             | That would be "io_uring: support for libuv". Which is a
             | common way to write headlines, so assuming the headline was
             | missing punctuation was reasonable.
             | 
             | (in case the title changes later, it's currently "io_uring
             | support for libuv")
        
             | josephg wrote:
             | Hm? The word "for" has the same meaning here as in "food
             | for kids". Read it as (io_uring support) for (libuv).
             | "Io_uring support" is being provided. Provided for what?
             | Provided for libuv.
        
             | gnfargbl wrote:
             | Looking at it again I think the problem is that both X and
             | Y are of the same type which makes the overall sentence
             | confusing, even though it is technically correct.
             | 
             | In a more normal construction ("food voucher support for
             | kids") it is obvious from context that the kids are being
             | given the support, because the converse would be
             | nonsensical.
        
             | earthling8118 wrote:
             | I think this is a slightly different case than the WSL one.
             | The headline is accurate, but perhaps a bit jarring. It
             | might have been better to say "io_uring support in libuv"
             | but I would say using from is not incorrect.
        
           | refulgentis wrote:
           | Toys for Tots, food for thought.
        
       | heyoni wrote:
       | Does this potentially mean you could write a sql driver using
       | libuv in python and benefit from async calls performance without
       | the main python scripts using any async libraries or conventions?
        
         | truth_seeker wrote:
         | asyncio event loop in Python uses `uvloop` which in based on
         | `libuv`
        
       | moralestapia wrote:
       | libuv is such an underrated piece of technology!
       | 
       | If you haven't yet, please go check it out, write a program with
       | it and be amazed.
       | 
       | So glad to be a contributor.
        
       | loeg wrote:
       | 8x throughput in what benchmark?
        
         | rwmj wrote:
         | Reading small chunks from /dev/zero. Avoiding lots of small
         | syscalls is the best case for io_uring, but also not uncommon
         | in real code.
        
           | gavinray wrote:
           | The commenter mentioning reading small chunks from _/
           | dev/zero_ says specifically GREATER than the stated x8
           | throughput, which makes me think it's x8 in the general
           | sense.
           | 
           | I could be mistaken though, it seems odd not to post any sort
           | of numbers/benchmarks.
        
       | alberth wrote:
       | Does this mean that NodeJS apps will gain 8x throughout?
        
         | truth_seeker wrote:
         | Only if they are highly I/O bound.
         | 
         | For example, implementing tcp/http/udp proxy servers. Static
         | file servers too can benefit greatly.
        
           | bhaney wrote:
           | Based on an exchange in the PR, it sounds like they have to
           | be specifically bound on file I/O to see an improvement, not
           | network I/O.
           | 
           | > is this PR just for files or also for network operations?
           | 
           | > Just file operations for now.
        
             | truth_seeker wrote:
             | Ouch ! I missed that comment.
             | 
             | Not sure, why they ignored socket, it would be have been
             | great addition to NodeJS/Python stack. Let's hope they make
             | it happen in near future release schedule.
        
               | junon wrote:
               | io_uring was made primarily for filesystem operations and
               | is most optimized for that use case. Other file
               | descriptor types have to be explicitly handled by the
               | kernel side of the io_uring implementation, and while
               | network calls are among those that have been, they still
               | all require different handling in some cases.
        
           | Misdicorl wrote:
           | Nit: Syscall bound, not necessarily I/O bound.
        
         | biorach wrote:
         | If the app's workload is quite similar to whatever benchmark
         | showed the 8x improvement, then yes.
         | 
         | Otherwise, i.e. in the real world, it's very unlikely to be
         | that much. High throughout workloads should see improvement,
         | but each application is different.
        
         | binarymax wrote:
         | I don't know why you're being downvoted, because for most
         | people that don't work with low level syscalls this is the kind
         | of question they have.
         | 
         | From what I understand, some async operations will be faster in
         | node on newer versions of the linux kernel, when node uses a
         | version of libuv that contains this PR.
        
       | truth_seeker wrote:
       | Libraries, VMs, Runtimes backed by libuv :
       | 
       | https://github.com/libuv/libuv/blob/v1.x/LINKS.md
        
       ___________________________________________________________________
       (page generated 2023-05-28 23:00 UTC)