io_uring is the new API for doing asynchronous IO on linux. It is particularly good for doing disk IO.
fio is a tool for benchmarking and testing IO on linux. It is able to use io_uring and it lets us configure how it uses io_uring in depth.
In this post we will go through some different configurations that are all described in the io_uring document and see what parameters make the most impact on file IO(direct_io) performance when using io_uring.
We are using a machine with:
nvme.poll_queues=16
.fio can be called like fio my_config
with a config file. Our baseline config file is this:
[global]
direct=1
bs=4K
rw=randread
ioengine=io_uring
iodepth=64
size=16g
hipri=0
fixedbufs=0
registerfiles=0
sqthread_poll=0
numjobs=1
[job0]
filename=/root/testfile
Configuration | Bandwidth (avg) | Latency Distribution (usec) | IOPS (avg) |
---|---|---|---|
Baseline | 936.54 MiB/s | 250=9.40%, 500=90.60% | 239754.41 |
WITH hipri | 1203.73 MiB/s | 250=99.72%, 500=0.28% | 308154.52 |
WITH sqthread_poll | 1383.20 MiB/s | (Not reported) | 354098.26 |
WITH fixedbufs | 996.56 MiB/s | 250=68.35%, 500=31.62% | 255118.94 |
WITH registeredfiles | 951.76 MiB/s | 250=20.77%, 500=79.23% | 243649.71 |
WITH ALL | 1788.14 MiB/s | (Not reported) | 457763.11 |
WITHOUT registeredfiles | 1787.38 MiB/s | (Not reported) | 457570.33 |
WITHOUT fixedbufs | 1617.83 MiB/s | (Not reported) | 414164.40 |
WITHOUT sqthread_poll | 1318.05 MiB/s | 250=99.53%, 500=0.47% | 337420.33 |
WITHOUT hipri | 1508.15 MiB/s | (Not reported) | 386087.33 |
Using the base config.
[global]
direct=1
bs=4K
rw=randread
ioengine=io_uring
iodepth=64
size=16g
hipri=0
fixedbufs=0
registerfiles=0
sqthread_poll=0
numjobs=1
[job0]
filename=/root/testfile
bw ( KiB/s): min=915616, max=966640, per=100.00%, avg=959017.18, stdev=10325.42, samples=34
lat (usec) : 250=9.40%, 500=90.60%, 750=0.01%, 1000=0.01%
iops : min=228904, max=241660, avg=239754.41, stdev=2581.25, samples=34
Same as base config except hipri=1
bw ( MiB/s): min= 1152, max= 1210, per=100.00%, avg=1203.73, stdev=10.63, samples=27
lat (usec) : 250=99.72%, 500=0.28%, 750=0.01%, 1000=0.01%
iops : min=295052, max=309898, avg=308154.52, stdev=2721.09, samples=27
Same as base config except sqthread_poll=1
bw ( MiB/s): min= 1352, max= 1391, per=100.00%, avg=1383.20, stdev= 8.14, samples=23
iops : min=346314, max=356152, avg=354098.26, stdev=2082.96, samples=23
There is no latency reported when using sqthread_poll
.
Same as base config except fixedbufs=1
bw ( KiB/s): min=980920, max=1031152, per=100.00%, avg=1020475.50, stdev=10727.21, samples=32
lat (usec) : 250=68.35%, 500=31.62%, 750=0.02%, 1000=0.01%
iops : min=245230, max=257788, avg=255118.94, stdev=2681.88, samples=32
Same as base config except registeredfiles=1
bw ( KiB/s): min=924768, max=979736, per=100.00%, avg=974597.88, stdev=9114.23, samples=34
lat (usec) : 250=20.77%, 500=79.23%, 750=0.01%, 1000=0.01%
iops : min=231192, max=244934, avg=243649.71, stdev=2278.60, samples=34
Enabling all features.
[global]
direct=1
bs=4K
rw=randread
ioengine=io_uring
iodepth=64
size=16g
hipri=1
fixedbufs=1
registerfiles=1
sqthread_poll=1
numjobs=1
[job0]
filename=/root/testfile
bw ( MiB/s): min= 1748, max= 1805, per=100.00%, avg=1788.14, stdev=15.05, samples=18
iops : min=447624, max=462126, avg=457763.11, stdev=3852.45, samples=18
This unsurprisingly gives the best results.
All features enabled except registedfiles
.
bw ( MiB/s): min= 1770, max= 1794, per=100.00%, avg=1787.38, stdev= 6.11, samples=18
iops : min=453220, max=459434, avg=457570.33, stdev=1564.26, samples=18
Doesn't seem to have much of an effect. Some metrics are even better.
All features enabled except fixedbufs
.
bw ( MiB/s): min= 1594, max= 1623, per=100.00%, avg=1617.83, stdev= 6.34, samples=20
iops : min=408218, max=415512, avg=414164.40, stdev=1622.91, samples=20
All features enabled except sqthread_poll
.
bw ( MiB/s): min= 1270, max= 1327, per=100.00%, avg=1318.05, stdev=11.40, samples=24
lat (usec) : 250=99.53%, 500=0.47%, 750=0.01%, 1000=0.01%
iops : min=325160, max=339936, avg=337420.33, stdev=2917.80, samples=24
All features enabled except hipri
(IO polling mode).
bw ( MiB/s): min= 1503, max= 1513, per=100.00%, avg=1508.15, stdev= 3.30, samples=21
iops : min=384848, max=387366, avg=386087.33, stdev=843.81, samples=21