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.
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.
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.
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.
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.
12 comments
[ 3.3 ms ] story [ 24.2 ms ] threadI see it’s 0.15.1 in the zon file, but that should also be part of the post somewhere.
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.
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/
Planning to add random reads with 4K and 512 blocksize to the example so I can measure IOPS too
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.
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.