我正在我的 Linux 服务器上对 NVMe SSD 进行基准测试,目的是实现产品规格中提到的 IOPS、BW 和延迟值。
我使用 FIO 作为工作负载生成器,最初使用 libaio 作为 I/O 引擎,但随着我深入存储领域,我意识到它是一个过时的 API,由于其损坏而无法修复。仅针对无缓冲访问提供异步操作的局限性以及系统调用的巨大开销。
这论文:《理解现代存储 API:对 libaio、SPDK 和 io_uring 的系统研究》,帮助我全面了解完成 I/O 命令的后端操作,并通过扫描设备数量、核心数量对三者进行比较计数和(软件)队列深度。然而,由于不在应用程序开发的范围内,有一些参数没有得到解决,例如作业数量(充当不同的工作人员/进程)、线程、不同的块大小和测试类型(seq/随机 R/W),这会严重影响数字。
我的问题是:每个库都能够使 SSD 饱和(即提供规范中提到的数字)吗?如果是,那么可以使用任何给定的库进行基准测试吗?通过基准测试,我在这里指的是在不同配置(如单核/多核、单线程/多线程、R/W 组合等)中实现最大吞吐量和最小延迟的方法进行概要分析。如果不是,那么是否意味着像 libaio 这样的过时技术永远无法与现代设备速度相匹配,并且不应再使用它(因为使用操作系统级别的瓶颈来定义设备速度是不公平的)?
我认为基准测试只能由 API 来完成,该 API 也用于对设备进行基准测试的应用程序。但这感觉违反直觉,因为对硬件设备进行基准测试不应受到不相关的操作系统操作的影响,这甚至不是应用程序的属性。我还想知道与普通同步 I/O 相比,找到操作每个步骤中的延迟开销的方法。
我觉得这里的事情记录不足,很想获得该领域经验丰富的人的更深入的理解和想法。谢谢!
答案1
我的问题是:每个库都能够使 SSD 饱和(即提供规范中提到的数字)吗?
io_uring
开销较小,因此速度更快。但如果您的 CPU 足够快,libaio
也可以使 SSD 饱和。
我的测试
-ioengine=libaio -numjobs=1
::
iops : min=286708, max=386670, avg=381760.92, stdev=13237.78, samples=59
-ioengine=io_uring -numjobs=1
:
iops : min=399008, max=414024, avg=409571.12, stdev=2658.33, samples=59
(+7%)
-ioengine=libaio -numjobs=2
:
iops : min=779822, max=814588, avg=805774.92, stdev=2274.38, samples=118
-ioengine=io_uring -numjobs=2
:
iops : min=438596, max=853962, avg=810650.24, stdev=38096.63, samples=118
(差异小于1%)
-ioengine=libaio -numjobs=4
:
iops : min=843282, max=1160188, avg=1131725.17, stdev=12340.14, samples=236
-ioengine=io_uring -numjobs=4
:
iops : min=1031955, max=1163986, avg=1140789.00, stdev=5196.52, samples=236
(再次相差不到1%)
进一步增加numjobs
并不会改变任何事情,看起来SSD已经饱和了。
fio
完整命令行:
fio -ioengine=XXX -direct=1 -name=test -bs=4k -iodepth=32 -rw=randread -runtime=30 -filename=/dev/nvmeYYY -numjobs=ZZZ -group_reporting
SSD是三星pm9a3