12 comments

[ 3.3 ms ] story [ 24.2 ms ] thread
Zig is currently undergoing lots of breaking changes in the IO API and implementation. Any post about IO in zig should also mention the zig version used.

I see it’s 0.15.1 in the zon file, but that should also be part of the post somewhere.

This doesn't use std except the IoUring API so it doesn't depend on the new changes
I see you use a hard-coded constant ALIGN = 512. Many NVMe drives actually allow you to raise the logical block size to 4096 by re-formatting (nvme-format(1)) the drive.
I realise this and also implemented it properly here before: https://github.com/steelcake/io2/blob/fd8b3d13621256a25637e3...

Just opted to use fixed 512 byte alignment in this library since all decent SSDs I have encountered so far are ok with 512 byte file alignment and 64 byte memory alignment.

This makes the code a bit simpler both in terms of the allocator and the file operations.

Interesting how an implementation using FreeBSDs AIO would compare.
why not use page allocator to get aligned memory instead of overallocating?
I was doing heavier computations to create write buffers and this actually made a bit of a difference before. Reverting to page_allocator now since it doesn't make a difference with new code.
7 GB/s at 512 KB block size is only ~14,000 IO/s which is a whopping ~70 us/IO. That is a trivial rate for even synchronous IO. You should only need one inflight operation (prefetch 1) to overlap your memory copy (to avoid serializing the IO with the memory copy) to get the full IO bandwidth.

Their referenced previous post [1] demonstrates ~240,000 IO/s when using basic settings. Even that seems pretty low, but is still more than enough to completely trivialize this benchmark and saturate the hardware IO with zero tuning.

[1] https://steelcake.com/blog/comparing-io-uring/

IOPS depends on the size of the individual IO and also the SSD. I was just trying to see if it is possible to reach max disk READ/WRITE.

Planning to add random reads with 4K and 512 blocksize to the example so I can measure IOPS too

I'm not very familiar with zig and was kind a struggling to follow the code and maybe that's why I couldn't find where the setting was being set up, but in case it's not, be sure to also use registered file descriptors with io_uring as they make a fairly big difference.
I added registering file descriptors now.

It didn't make any difference when I was benchmarking with fio but I didn't use many threads so not sure.

I added it anyway since I saw this comment and also the io_uring document says it should make a difference.

> The result I get from fio is 4.083 GB/s write, … The result for the diorw example in zig is 3.802 GB/s write….

4.083 / 3.802 = 1.0739

2^30 / 10^9 = 1.0737

I think the same rate was likely achieved but there is confusion between GiB and GB.