4 ms·
why epoll at all, the new hotness is io_uring, fire away your iovecs, check back later
by bfrog 4y ago
why epoll at all, the new hotness is io_uring, fire away your iovecs, check back later
- rwmj 4y agoYou can go from select/poll to epoll relatively easily, but I've found that to use io_uring you have to substantially rearchitect your whole program (if you want any performance benefit). Actually I'd love to be wrong about this, but I've not found a way to easily retrofit io_uring into programs/libraries that are already using either synchronous operations or poll(2).
- jasonzemos 4y agoio_uring is basically a drop-in for epoll. It has an intrinsic performance benefit because multiple operations can be both submitted and completed in a single action. Rearchitecting is only optional when going further by replacing standalone syscalls with io_uring operations. In the case of poll(2) I believe it should be no more difficult than refactoring for epoll.
- wahern 4y agoWith io_uring, every line in an application that calls read/recv needs to be refactored, along with much of the surrounding context. io_uring doesn't replace poll/epoll, it effectively replaces typical event loop frameworks. You can integrate io_uring into pre-existing event loop frameworks, but the event loop framework will end up as a 99% superfluous wrapper, at least on Linux. Note that many applications don't use event loop frameworks. For simple applications they can be overkill. Even for more complex applications, it may be cleaner to use restartable semantics (i.e. same semantics as read--just call me again), especially for libraries or components that want to be event loop agnostic.
- jasonzemos 4y ago> io_uring doesn't replace poll/epoll, it effectively replaces typical event loop frameworks. I'm sorry but that statement is incorrect. The same functionality is accomplished by either io_uring or epoll. > every line in an application that calls read/recv needs to be refactored If the GP finds it easy to refactor from poll to epoll they will find it no different to refactor from poll to io_uring; the only caveat being they won't exceed epoll's performance with the io_uring until the standalone syscalls are further refactored. They don't need to be. The statement is incorrect.
- gavinray 4y agoYou can use userspace Coroutines/fibers implementations to wire in async io_uring into existing synchronous code and maintain the facade of the code still being synchronous How easy/feasible this is depends on the language. In C++, Rust, Zig, Java (Loom fibers), and Kotlin I know for a fact it's doable Other languages I'm not sure what the experience is like
- darksensei 4y agoBut in this case are you really reaping any benefit of io_uring, if your existing code is still synchronous (except your io_uring layer)? It seems to me to see any substantial benefit, you'd have to propagate async throughout your codebase, which would require rewriting your existing code to use some async primitive. I guess something like Java Loom does help you mask this, however.
- cbsmith 4y agoIt's all proactor vs. reactor. Basically the same as the differences between select/poll and AIO. If you're familiar with the two models, it's not THAT hard to shift between them, but I wouldn't deny that there is work involved.
- drpixie 4y agoDoes anyone feel that the Linux API (and so the kernel) is slowly getting more and more complex and cumbersome?
- rwmj 4y agoThat ship sailed a very long time ago - arguably after V7 if you consider Unix as a whole. The more important questions: Do the various APIs interact in ways which are insecure? Are corner-cases being properly tested? Are old interfaces properly documented as deprecated (with replacements)? Are the interfaces that you actually need easy to use? Does the kernel maintain backwards compatibility. Linux does fairly well on many of these with some exceptions (hello there extended filesystem attributes API).