本测试用于验证 Zynq UltraScale+ MPSoC 平台上从 Linux 文件系统到 NVMe SSD 的实际读写性能。测试工具使用的是fio,考虑到实际 DDAQ 写盘链路还包括 PL 数据产生、DMA 搬运、DDR 缓冲、PS 端软件处理和文件写入等环节,实际端到端写盘速度可能低于 fio 测试结果。
fio(Flexible I/O Tester)是 Linux 下常用的存储性能测试工具,可以生成可控的同步或异步 I/O 负载,并统计:
顺序或随机读写带宽;
IOPS(每秒 I/O 次数);
提交延迟、完成延迟和总延迟;
不同延迟百分位;
I/O 队列深度分布;
CPU 用户态、内核态占用;
块设备利用率。
fio 可以使用 O_DIRECT 绕过 Linux 页缓存,并通过 libaio 或 io_uring 同时提交多条异步 I/O 请求,因此适合测量 NVMe SSD 与 PCIe 链路的真实吞吐能力。
参数 | 本测试取值 | 含义 |
|---|---|---|
| 自定义 | 测试任务名称 |
| SSD挂载目录下的测试文件 | 只操作指定测试文件,不直接覆盖整个块设备 |
| 1G~64G | 本轮测试写入或读取的数据量 |
|
| 顺序写入或顺序读取 |
|
| 每次应用层 I/O 请求为1MiB |
|
| 使用 |
|
| 使用 Linux 原生异步 I/O |
|
| 同时保持最多32个未完成请求 |
|
| 使用一个 fio 作业进程 |
|
| 任务结束时刷新文件数据 |
| 启用 | 汇总显示任务结果 |
字段 | 含义 |
|---|---|
| 测试过程中没有发生 fio 错误 |
| 平均传输带宽 |
| 每秒完成的 I/O 请求数;本测试块大小为1MiB,因此数值与 MiB/s 接近 |
| fio 从用户态向内核提交请求所需时间 |
| 请求提交后到完成返回的时间 |
|
|
| 测试期间实际队列深度分布 |
| 块设备忙碌程度,接近100%通常表示设备或链路已接近饱和 |
项目 | 配置 |
|---|---|
SoC | Xilinx Zynq UltraScale+ MPSoC |
DDR | 4GiB DDR4 |
PCIe控制器 | ZynqMP PS PCIe Root Port |
PCIe配置 | PCIe Gen2 ×4 |
SSD | Apacer AS2280P4 512GB |
SSD固件 |
|
虽然 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内核驱动 |
|
fio | 3.32 |
nvme-cli | 1.13 |
fio I/O引擎 | 支持 |
多次进行测试,测试文件大小如下:
1GiB、2GiB、4GiB、8GiB、16GiB、32GiB、64GiB
为了减小前一轮写入对后一轮动态 SLC缓存状态的影响,每轮测试采用以下流程:
删除上一轮测试文件;
执行 sync;
如果系统提供 fstrim,对 ext4 挂载点发送 TRIM;
空闲180秒,让SSD进行缓存折叠和垃圾回收;
使用相同的 1MiB + O_DIRECT + libaio + iodepth=32 参数进行写入;
保存 fio 完整输出和每秒带宽日志;
记录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
测试文件大小 | 平均带宽(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过热造成的。
1GiB、2GiB、4GiB和8GiB写入带宽基本稳定在1532~1541MiB/s;
16GiB平均带宽为1516MiB/s,相比8GiB下降约1.6%;
32GiB平均带宽为1494MiB/s,相比8GiB下降约3.0%,但仍维持在约1.5GiB/s;
64GiB平均带宽下降至1209MiB/s,相比8GiB下降约21.5%;
64GiB测试同时出现1548MiB/s峰值和280MiB/s最低值,说明写入过程中发生了明显的速度阶段切换,而不是从开始到结束始终保持1209MiB/s;
64GiB测试的99%完成延迟由前几轮的约27~42ms上升至113ms,最大完成延迟约217ms,表明SSD内部出现缓存折叠或垃圾回收造成的长尾延迟。
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插件快速发布