-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement io_uring support for FileStream #51985
Comments
Tagging subscribers to this area: @carlossanlop Issue DetailsWe have recently invested a lot of time in rewriting
We (owners of System.IO) have a lot of other high-priority things on our schedule for .NET 6 (like full symbolic links support) and since most of our customers are not using the latest Linux kernels, we are most probably won't be able to implement it on our own for .NET 6. But we would love to provide any help necessary (code reviews, testing) for a contributor that would be willing to implement it. Having said that, I am marking this issue as "up-for-grabs". If we won't find a contributor for .NET 6, we are going to include this in .NET 7 planning and deliver it in .NET 7.
|
@tmds @damageboy @benaadams would any of you be interested? |
Many of the io_uring benchmarks are performed on a single thread that needs no synchronization. We won't be able to achieve the gains measured there because we need to synchronize and hop between threads. That will definitely cost us something. Functionally, using io_uring allows to cancel the the on-going operations. This is not supported with the current sync-on-ThreadPool implementation. So this is a functional gain. I'll let you know if I find time to work on this. I'd need your, and others, help to optimize the thread/synchronization stuff. |
I thought in our last conversation we decided that we should gate this feature on 5.10 since the support between 5.5 and 5.7 is patchy. It seems like 5.10 would be great. As context, .NET 6 container images use Debian 11 by default and the second most popular are Alpine, which for .NET 6 will be 3.13+. Here's what I found on kernel versions.
Interesting context: https://news.ycombinator.com/item?id=27382299 |
WSL is already |
@adamsitnik What is |
|
io_uring is a pretty sweet, modern io api in Linux kernel 5.1+ Uses producer-consumer ring buffers to achieve lock-free asynchrony with low-latency, high throughput, and minimal memory copies, like other notable recent architectures: |
Windows also should receive IO Rings API soon: |
https://www.phoronix.com/scan.php?page=news_item&px=8M-IOPS-Per-Core-Linux An engineer from Facebook is pushing the performance quite aggressively for IO_uring in Linux. So I imagine there would be significant performance gains to be had if utilized in dotnet for Linux. |
I wonder what it would take to achieve performance gains with io_uring on non-benchmark workloads. If IOs are issued just like before except using a new call mechanism, I do not see why this would be much faster. Achieving batching benefits would take new APIs that are not currently available with On the web, there are various reports by people who couldn't reproduce performance gains. This is further evidence that the gains might accrue only when the application is structured suitably. So maybe it takes new, specialized APIs for applications to harness this fully. Since Windows appears to have similar mechanisms now, there could be a common abstraction for both. Low latency IO has been a trend for the last couple of years. We have SSDs now that are insanely fast. Networks have become much lower latency as well (e.g. RDMA). So maybe there's value in addressing such devices with a new API. |
All existing .NET APIs are not batching. For example, they deal with each |
Another improvement: I imagine a whole new set of APIs might be needed, or maybe |
Is there any news on this topic? I think |
Isn't that what |
We are not planning to add io_uring support for .NET 7. The main reason for that is currently in most common scenarios we would observe a perf regression. Currently in io_uring the producer and consumer (the thread that adds and removes work items to/from the ring) needs to be the same thread. It just does not work well with our current Thread Pool model.
@ayende is right, https://devblogs.microsoft.com/dotnet/file-io-improvements-in-dotnet-6/#scatter-gather-io |
May be FileStream is bad place for io_uring? Queue rings can be implemented in software level by System.Threading.Tasks.Dataflow primitives, and I think that io_uring place in .NET must be in separate async only primitive. |
Any movement on adding io_uring? |
@Scooletz thanks for sharing! Based on https://github.com/davidtos/JUring?tab=readme-ov-file#thread-safety:
It seems that what I wrote in #51985 (comment) is still true. Other things has changed, as Windows has introduced a similar API (IoRing). But there is still no such API for macOS and we very rarely introduce non-cross platform APIs. Moreover, when looking at JURing API it's clear that the target audience would be "superusers" and it would be possible to run into issues when using it wrong. |
Doesn't need to be same thread (isn't bonded), just a single thread at a time (not threadsafe). So could do something based on ConcurrentQueue etc |
We have recently invested a lot of time in rewriting
FileStream
on Windows. We have keptio_uring
in mind and after recent refactoring, it should be now much easier to implement the support:FileStream
API.FileStream
can choose the strategy at runtime. In the case ofLinux
, it could detect the kernel version and just use the new strategy for newer kernels (5.5+). It means that the day our customers update their kernel version, .NET could start usingio_uring
without a .NET update.IoUringStrategy
) don't need to worry about buffering at allruntime/src/libraries/System.Private.CoreLib/src/System/IO/Strategies/FileStreamHelpers.Windows.cs
Lines 59 to 60 in 2223bab
IoUringStrategy
would only need to implementReadAsync
andWriteAsync
support.We (owners of System.IO) have a lot of other high-priority things on our schedule for .NET 6 (like full symbolic links support) and since most of our customers are not using the latest Linux kernels, we are most probably won't be able to implement it on our own for .NET 6. But we would love to provide any help necessary (code reviews, testing) for a contributor that would be willing to implement it. Having said that, I am marking this issue as "up-for-grabs".
If we won't find a contributor for .NET 6, we are going to include this in .NET 7 planning and deliver it in .NET 7.
The text was updated successfully, but these errors were encountered: