NVMe SSD写盘速度测试报告

1. 测试目的

本测试用于验证 Zynq UltraScale+ MPSoC 平台上从 Linux 文件系统到 NVMe SSD 的实际读写性能。测试工具使用的是fio,考虑到实际 DDAQ 写盘链路还包括 PL 数据产生、DMA 搬运、DDR 缓冲、PS 端软件处理和文件写入等环节,实际端到端写盘速度可能低于 fio 测试结果。

2. fio 测试工具简介

fio(Flexible I/O Tester)是 Linux 下常用的存储性能测试工具,可以生成可控的同步或异步 I/O 负载,并统计:

  • 顺序或随机读写带宽;

  • IOPS(每秒 I/O 次数);

  • 提交延迟、完成延迟和总延迟;

  • 不同延迟百分位;

  • I/O 队列深度分布;

  • CPU 用户态、内核态占用;

  • 块设备利用率。

fio 可以使用 O_DIRECT 绕过 Linux 页缓存,并通过 libaioio_uring 同时提交多条异步 I/O 请求,因此适合测量 NVMe SSD 与 PCIe 链路的真实吞吐能力。

主要测试参数说明

参数

本测试取值

含义

--name

自定义

测试任务名称

--filename

SSD挂载目录下的测试文件

只操作指定测试文件,不直接覆盖整个块设备

--size

1G~64G

本轮测试写入或读取的数据量

--rw

write / read

顺序写入或顺序读取

--bs

1M

每次应用层 I/O 请求为1MiB

--direct

1

使用 O_DIRECT,尽量绕过 Linux 页缓存

--ioengine

libaio

使用 Linux 原生异步 I/O

--iodepth

32

同时保持最多32个未完成请求

--numjobs

1

使用一个 fio 作业进程

--end_fsync

1

任务结束时刷新文件数据

--group_reporting

启用

汇总显示任务结果

关键输出字段说明

字段

含义

err=0

测试过程中没有发生 fio 错误

BW

平均传输带宽

IOPS

每秒完成的 I/O 请求数;本测试块大小为1MiB,因此数值与 MiB/s 接近

slat

fio 从用户态向内核提交请求所需时间

clat

请求提交后到完成返回的时间

lat

slat + clat,即总延迟

IO depths

测试期间实际队列深度分布

util

块设备忙碌程度,接近100%通常表示设备或链路已接近饱和

3. 测试环境

硬件环境

项目

配置

SoC

Xilinx Zynq UltraScale+ MPSoC

DDR

4GiB DDR4

PCIe控制器

ZynqMP PS PCIe Root Port

PCIe配置

PCIe Gen2 ×4

SSD

Apacer AS2280P4 512GB

SSD固件

H220719b

alt text 虽然 SSD 支持 PCIe Gen3 ×4,但在官网相关文档上查询到当前使用的 Zynq UltraScale+ MPSoC 的 PS 端的 PCIe 通道并不支持 PCIe 3.0。因此 ZynqMP 主机配置为 PCIe Gen2 ×4。Gen2 每条 Lane 为5GT/s,经 8b/10b 编码后,每条 Lane 理论有效数据率约500MB/s,四条 Lane 单向理论上限约2GB/s。

LnkCap: Port #0, Speed 8GT/s, Width x4
LnkSta: Speed 5GT/s (downgraded), Width x4

软件环境

项目

版本/配置

Vivado

2023.2

Vitis

2023.2

PetaLinux

2023.2

Linux内核

6.1.30-xilinx-v2023.2

NVMe内核驱动

CONFIG_BLK_DEV_NVME=y

fio

3.32

nvme-cli

1.13

fio I/O引擎

支持 libaioio_uringio_uring_cmd

4. 测试过程

多次进行测试,测试文件大小如下:

1GiB、2GiB、4GiB、8GiB、16GiB、32GiB、64GiB

为了减小前一轮写入对后一轮动态 SLC缓存状态的影响,每轮测试采用以下流程:

  1. 删除上一轮测试文件;

  2. 执行 sync

  3. 如果系统提供 fstrim,对 ext4 挂载点发送 TRIM;

  4. 空闲180秒,让SSD进行缓存折叠和垃圾回收;

  5. 使用相同的 1MiB + O_DIRECT + libaio + iodepth=32 参数进行写入;

  6. 保存 fio 完整输出和每秒带宽日志;

  7. 记录SMART温度与错误状态。

测试命令:

MNT=/run/media/nvme0n1
TEST="$MNT/fio_size_test.bin"
RESULTS="/tmp/fio_size_results_$(date +%Y%m%d_%H%M%S)"

mkdir -p "$RESULTS"

for SIZE in 1 2 4 8 16 32 64
do
    echo
    echo "========== ${SIZE}GiB WRITE TEST =========="

    rm -f "$TEST"
    sync

    if command -v fstrim >/dev/null 2>&1; then
        fstrim "$MNT"
    fi

    echo "等待180秒,让SSD缓存回收..."
    sleep 180

    fio --name="write_${SIZE}G" \
      --filename="$TEST" \
      --size="${SIZE}G" \
      --rw=write \
      --bs=1M \
      --direct=1 \
      --ioengine=libaio \
      --iodepth=32 \
      --numjobs=1 \
      --end_fsync=1 \
      --write_bw_log="$RESULTS/${SIZE}G" \
      --log_avg_msec=1000 \
      --group_reporting 2>&1 |
    tee "$RESULTS/${SIZE}G.txt"

    nvme smart-log /dev/nvme0 |
    grep -E 'critical_warning|temperature|percentage_used|media_errors'
done

rm -f "$TEST"
sync

cp -a "$RESULTS" "$MNT/"
echo "结果目录:$RESULTS"

结果读取命令:

for SIZE in 1 2 4 8 16 32 64
do
    echo "=== ${SIZE}GiB ==="
    grep -E 'WRITE: bw=|write: IOPS=' "$RESULTS/${SIZE}G.txt"
done

5. 测试结果

写入性能汇总

测试文件大小

平均带宽(MiB/s)

平均带宽(MB/s)

运行时间

采样最低带宽(MiB/s)

采样最高带宽(MiB/s)

平均完成延迟

99%完成延迟

设备利用率

测试后温度

1GiB

1538

1612

0.666s

20.29ms

33.82ms

79.03%

30°C

2GiB

1532

1606

1.337s

1532

1532

20.46ms

26.61ms

89.40%

32°C

4GiB

1538

1612

2.664s

1534

1537

20.45ms

27.92ms

94.29%

33°C

8GiB

1541

1616

5.315s

1536

1547

20.42ms

26.61ms

97.29%

35°C

16GiB

1516

1590

10.808s

1472

1548

20.78ms

36.96ms

98.71%

38°C

32GiB

1494

1567

21.932s

1446

1547

21.10ms

41.68ms

99.42%

40°C

64GiB

1209

1267

54.224s

280

1548

26.16ms

113ms

99.86%

40°C

说明:1GiB测试只持续0.666秒,fio只能获得极少的带宽采样点,因此不列出可靠的最低/最高采样带宽;其设备利用率也受到测试时间过短和统计粒度影响,不能据此判断SSD未被充分利用。

结果一致性与健康状态

所有测试均满足:

err=0
critical_warning=0
percentage_used=0%
media_errors=0

测试过程中没有出现 PCIe AER、NVMe timeout、I/O error 或控制器 reset。温度随写入量由30°C逐步升至40°C,但未触发温控管理,说明本轮降速不是由SSD过热造成的。

带宽变化特征

  1. 1GiB、2GiB、4GiB和8GiB写入带宽基本稳定在1532~1541MiB/s;

  2. 16GiB平均带宽为1516MiB/s,相比8GiB下降约1.6%;

  3. 32GiB平均带宽为1494MiB/s,相比8GiB下降约3.0%,但仍维持在约1.5GiB/s;

  4. 64GiB平均带宽下降至1209MiB/s,相比8GiB下降约21.5%;

  5. 64GiB测试同时出现1548MiB/s峰值和280MiB/s最低值,说明写入过程中发生了明显的速度阶段切换,而不是从开始到结束始终保持1209MiB/s;

  6. 64GiB测试的99%完成延迟由前几轮的约27~42ms上升至113ms,最大完成延迟约217ms,表明SSD内部出现缓存折叠或垃圾回收造成的长尾延迟。

6. 结果分析

整体性能

1~8GiB测试稳定在约1.53~1.54GiB/s,16~32GiB仍保持约1.49~1.52GiB/s,已经接近 PCIe Gen2 ×4 在当前平台上的实际带宽上限。64GiB测试平均速度下降到1.21GiB/s,并出现最低280MiB/s和99%延迟113ms的低速区间。

大文件降速原因

主要原因是动态 SLC 缓存。小文件可以全部写入高速缓存,因此保持约1.5GiB/s;写入量接近缓存容量后,SSD需要同时进行缓存折叠、NAND数据搬移和垃圾回收,导致可供主机写入的带宽下降并产生长尾延迟。动态缓存容量会随SSD剩余空间、此前写入、TRIM、空闲时间和固件策略变化,本轮结果显示明显降速发生在32GiB与64GiB之间。


本文章使用limfx的vscode插件快速发布