☰
iMX8存储性能测试全指南:eMMC、SD卡与DDR带宽评估
2026/10/15 1:19:41 网站建设 项目流程

1. 为什么存储性能测试在 iMX8 上是个绕不开的坎

拿到一块 iMX8 的板子,很多人第一反应是跑个dd看看读写速度,数字好看就收工。但实际项目里,存储性能这件事远比一个顺序读写数字复杂得多。iMX8 系列覆盖了从 iMX8M Mini、iMX8M Plus 到 iMX8QuadMax 等多个型号,不同型号的存储控制器、DDR 类型、外设接口差异很大,同一套测试方法在不同板子上得出的结论可能完全不一样。

存储性能测试的核心价值在于:它能帮你判断当前硬件设计是否满足应用需求、定位系统卡顿的根因、验证驱动配置是否正确、以及在量产前筛掉有隐患的存储器件。比如做视频录制的产品,eMMC 的持续写入带宽不够就会丢帧;做边缘计算的设备,DDR 带宽不足会让推理延迟飙升;做工业网关的场景,SD 卡随机读写太差会导致数据库频繁超时。

这篇文章面向的是拿到 iMX8 平台、需要做存储性能评估的嵌入式和系统工程师。我会把 eMMC、SD 卡、DDR、以及外部存储接口的测试方法、工具选型、参数解读、常见坑点都过一遍。内容基于 iMX8 平台的通用实践,具体寄存器地址和时钟配置请以你手上的参考手册为准。

2. 测试之前必须搞清楚的几个基础概念

2.1 顺序读写和随机读写的本质区别

很多人把存储性能等同于顺序读写速度,这是个常见的认知偏差。顺序读写指的是数据在存储介质上连续排列,控制器可以一次性发出大块传输请求,效率最高。随机读写则是数据分散在不同位置,每次都要重新寻址,开销大得多。

对于 iMX8 这类嵌入式平台,eMMC 的顺序读取通常能跑到 200-300 MB/s,但 4K 随机读取可能只有 5-15 MB/s,差距在二十倍以上。你的应用如果是大文件搬运(比如固件升级、视频存储),关注顺序性能;如果是数据库、日志系统、频繁的小文件操作,随机性能才是关键指标。

2.2 影响 iMX8 存储性能的硬件因素

iMX8 的存储性能不是孤立存在的,它受多个硬件环节制约:

  • 存储控制器配置:uSDHC 控制器的时钟频率、总线宽度(1-bit / 4-bit / 8-bit)、是否启用高速模式,直接决定上限。
  • DDR 类型与频率:LPDDR4 和 DDR4 的带宽差异明显,iMX8M 系列通常配 LPDDR4,iMX8Quad 则可能用 DDR4,频率从 1600 MT/s 到 3200 MT/s 不等。
  • 电源与信号完整性:存储器件供电不稳会导致降速重试,PCB 走线阻抗不匹配会引起误码,这些都会在性能数据上体现出来。
  • 温度:eMMC 在高温下可能触发热保护降速,工业级器件和消费级器件的温度表现差异很大。

2.3 测试工具的选择逻辑

iMX8 上跑 Linux 系统时,常用的存储测试工具有这几类:

工具适用场景优点局限
dd快速顺序读写摸底系统自带,命令简单只测顺序,不测随机
fio全面性能评估支持随机/顺序/混合,参数灵活需要交叉编译或移植
iozone文件系统级测试覆盖多种读写模式输出信息量大,解读需经验
bonnie++文件系统元数据测试侧重实际文件操作对嵌入式平台偏重
mmc-utilseMMC 专项测试可读器件健康状态功能偏底层,不测吞吐

我的建议是:先用dd做快速摸底,确认基本读写没问题;然后用fio做详细测试,覆盖顺序和随机场景;如果怀疑器件本身有问题,再用mmc-utils读 eMMC 的 EXT_CSD 寄存器看健康状态。

3. eMMC 性能测试的完整操作链路

3.1 测试前的环境准备与注意事项

在开始测试之前,有几件事必须先确认。第一,确保系统没有其他高负载进程在跑,用top或htop看一眼 CPU 和内存占用。第二,确认测试分区有足够空间,eMMC 写满后性能会断崖式下降。第三,如果是写测试,注意数据安全,别把系统分区写坏了。

挂载参数也会影响测试结果。比如noatime可以减少元数据写入,data=writeback和data=ordered对写入性能有影响。测试时建议统一挂载参数,否则数据没有可比性。

# 查看当前挂载参数 mount | grep mmcblk # 查看 eMMC 基本信息 cat /sys/block/mmcblk0/device/name cat /sys/block/mmcblk0/device/manfid cat /sys/block/mmcblk0/size

3.2 用 dd 做顺序读写快速摸底

dd是最简单的入门工具,虽然粗糙但足够快速判断存储是否正常工作。

# 顺序写测试:写入 1GB 数据,块大小 1MB dd if=/dev/zero of=/mnt/emmc/testfile bs=1M count=1024 conv=fdatasync # 顺序读测试:先清缓存,再读取 echo 3 > /proc/sys/vm/drop_caches dd if=/mnt/emmc/testfile of=/dev/null bs=1M count=1024 # 清理测试文件 rm /mnt/emmc/testfile

这里有几个细节值得注意。conv=fdatasync确保数据真正写入存储而不是停留在页缓存,不加这个参数测出来的数字会虚高。读测试前必须清缓存,否则数据从内存读取,测的是 DDR 速度而不是 eMMC 速度。

块大小的选择也有讲究。bs=1M测的是大块传输能力,适合评估顺序带宽;bs=4k则更接近随机小文件场景,但dd的随机性有限,只能作为粗略参考。

3.3 fio 的配置与参数解读

fio是嵌入式存储测试的主力工具。如果板子上没有预装,可以通过 Buildroot 或 Yocto 的包管理加上,也可以交叉编译后推送到板子。

# 顺序读测试 fio --name=seqread --filename=/mnt/emmc/testfile --rw=read \ --bs=1M --size=512M --numjobs=1 --iodepth=32 \ --ioengine=libaio --direct=1 --group_reporting # 顺序写测试 fio --name=seqwrite --filename=/mnt/emmc/testfile --rw=write \ --bs=1M --size=512M --numjobs=1 --iodepth=32 \ --ioengine=libaio --direct=1 --group_reporting # 4K 随机读测试 fio --name=randread --filename=/mnt/emmc/testfile --rw=randread \ --bs=4k --size=256M --numjobs=4 --iodepth=64 \ --ioengine=libaio --direct=1 --group_reporting # 4K 随机写测试 fio --name=randwrite --filename=/mnt/emmc/testfile --rw=randwrite \ --bs=4k --size=256M --numjobs=4 --iodepth=64 \ --ioengine=libaio --direct=1 --group_reporting

关键参数解释:--direct=1绕过页缓存,测的是真实存储性能;--iodepth是队列深度,eMMC 支持命令队列的话可以设高一些;--numjobs是并发任务数,模拟多线程场景。--ioengine=libaio是异步 IO 引擎,比同步模式更能压出存储的极限。

实测中我发现,iMX8M Mini 搭配主流 eMMC 5.1 器件时,顺序读通常在 250-300 MB/s,顺序写在 80-150 MB/s,4K 随机读在 8-15 MB/s,4K 随机写在 5-12 MB/s。如果你的数据明显低于这个范围,就要检查控制器配置或器件本身了。

3.4 测试结果的可重复性与对比方法

存储性能测试有个容易被忽视的问题:结果波动。同一块板子跑三次,顺序写可能差 10% 以上。要得到可靠结论,建议:

  • 每次测试前清缓存,保持环境一致
  • 至少跑三轮取平均值
  • 记录测试时的温度,高温降速很常见
  • 用同一份测试脚本,避免人为差异

对比不同板子或不同器件时,务必保证测试条件完全一致。我见过有人拿 A 板子的顺序读对比 B 板子的随机写,然后得出"A 比 B 快"的结论,这种对比毫无意义。

4. SD 卡与外部存储接口的测试要点

4.1 SD 卡性能测试的特殊性

SD 卡和 eMMC 虽然都是闪存,但测试时有几个额外注意点。SD 卡的性能高度依赖卡本身的质量,同一品牌不同批次都可能差异明显。另外,SD 卡通过 uSDHC 控制器连接,总线宽度和时钟频率对性能影响很大。

# 查看 SD 卡信息 cat /sys/block/mmcblk1/device/name cat /sys/block/mmcblk1/device/speed # SD 卡顺序写测试 dd if=/dev/zero of=/mnt/sdcard/testfile bs=1M count=512 conv=fdatasync # SD 卡随机读测试 fio --name=sdrandread --filename=/mnt/sdcard/testfile --rw=randread \ --bs=4k --size=128M --numjobs=2 --iodepth=32 \ --ioengine=libaio --direct=1 --group_reporting

SD 卡的性能通常比 eMMC 低不少,顺序读在 40-90 MB/s,顺序写在 20-60 MB/s,4K 随机性能更是差一个档次。如果你的应用对随机性能有要求,尽量用 eMMC 而不是 SD 卡。

4.2 USB 存储和 NVMe 扩展的测试思路

iMX8 部分型号支持 USB 3.0 和 PCIe,可以接 USB 存储或 NVMe SSD。这类外部存储的测试方法和 eMMC 类似,但要注意接口带宽可能成为瓶颈。比如 USB 3.0 理论带宽 5 Gbps,实际有效带宽约 400 MB/s,如果 SSD 本身能跑 500 MB/s,测出来会被接口限制。

# USB 存储测试 lsusb -t # 查看 USB 拓扑和速度 dd if=/dev/zero of=/mnt/usb/testfile bs=1M count=1024 conv=fdatasync # NVMe 测试(如果支持) nvme list fio --name=nvme_seqread --filename=/dev/nvme0n1 --rw=read \ --bs=128k --size=1G --iodepth=64 --ioengine=libaio --direct=1

测试外部存储时,建议先用lsusb -t或lspci确认链路速度,排除接口降速的可能。我遇到过 USB 3.0 设备实际跑在 USB 2.0 模式的情况,性能直接砍到十分之一,排查了半天才发现是线缆问题。

4.3 文件系统对测试结果的影响

同样的硬件,用 ext4、f2fs、ubifs 测出来的性能可能差很多。ext4 通用性好但随机写性能一般;f2fs 针对闪存优化,随机写表现更好;ubifs 主要用于裸 NAND,不适合 eMMC。

# 查看当前文件系统 df -T /mnt/emmc # 格式化测试(注意备份数据) mkfs.ext4 /dev/mmcblk0p2 mkfs.f2fs /dev/mmcblk0p2

如果应用对随机写敏感,可以试试 f2fs。但要注意 f2fs 在突然断电时的数据一致性不如 ext4,工业场景要权衡。

5. DDR 带宽测试与系统级性能关联

5.1 为什么 DDR 性能也会影响存储体验

很多人只测 eMMC 不测 DDR,这是个盲区。存储读写的数据最终要经过 DDR 中转,如果 DDR 带宽不足,存储性能也会被拖累。特别是在多任务场景下,CPU、GPU、VPU 都在抢 DDR 带宽,存储子系统的有效带宽会明显下降。

iMX8 的 DDR 控制器配置在 U-Boot 阶段就确定了,包括频率、时序参数、刷新策略等。这些参数如果没调好,DDR 带宽可能只有理论值的六七成。

5.2 用 memtester 和 stream 做内存带宽评估

# memtester 测试内存稳定性 memtester 256M 5 # stream 测试内存带宽(需要交叉编译) ./stream

memtester主要测稳定性,stream测的是实际带宽。iMX8M Plus 搭配 LPDDR4-3200 时,理论带宽约 12.8 GB/s,实测 stream 的 Copy 成绩通常在 3-5 GB/s,具体取决于控制器配置和测试方法。

如果 DDR 带宽明显偏低,可以检查 U-Boot 里的 DDR 配置参数,比如ddr_freq、ddr_timing等。这部分调试比较复杂,建议参考官方提供的 DDR 压力测试工具和配置模板。

5.3 存储与 DDR 的联合测试场景

最贴近实际应用的测试方法是模拟真实负载。比如同时跑视频解码和存储写入,观察存储性能是否下降。

# 后台跑存储写测试 fio --name=bgwrite --filename=/mnt/emmc/bgfile --rw=write \ --bs=1M --size=1G --ioengine=libaio --direct=1 & # 同时跑内存带宽测试 ./stream # 观察存储写入速度变化

这种联合测试能暴露单一测试发现不了的问题。我遇到过单独测 eMMC 顺序写能跑 120 MB/s,但同时跑视频解码时掉到 60 MB/s 的情况,原因是 DDR 带宽被 VPU 抢占,存储控制器的 DMA 传输效率下降。

6. 实测中踩过的坑与排查经验

6.1 测试数据虚高的几种典型情况

第一种是没清缓存。读测试前不清缓存,数据从 DDR 返回,测出来是内存速度。第二种是没加conv=fdatasync,写数据停留在页缓存,dd命令返回时数据还没落盘。第三种是测试文件太小,文件系统还没进入稳定状态就测完了。

# 正确的清缓存方式 sync echo 3 > /proc/sys/vm/drop_caches # 确认缓存已清 free -h

6.2 eMMC 降速与健康状态排查

eMMC 用久了会磨损,性能下降是正常现象。用mmc-utils可以读器件的健康状态:

# 读取 eMMC 寿命信息 mmc extcsd read /dev/mmcblk0 | grep -i life mmc extcsd read /dev/mmcblk0 | grep -i pre_eol # 查看 eMMC 当前速度模式 mmc extcsd read /dev/mmcblk0 | grep -i speed

如果pre_eol显示接近耗尽,说明器件寿命快到了,性能下降不可逆。另外,eMMC 在高温下会触发热保护,速度模式可能从 HS400 降到 HS200 甚至 DDR52,这时候测出来的性能会明显偏低。

6.3 控制器配置错误的识别与修正

uSDHC 控制器的配置错误是性能异常的常见原因。检查设备树里的bus-width、max-frequency、no-1-8-v等属性是否正确。比如支持 HS400 的 eMMC 如果设备树里只配了 4-bit 总线,性能直接砍半。

# 查看当前 SD/MMC 控制器状态 cat /sys/kernel/debug/mmc0/ios cat /sys/kernel/debug/mmc1/ios

输出里的clock、bus width、timing spec能直接反映当前工作模式。如果timing spec显示的是sd hs而不是mmc hs400,说明高速模式没启用,需要检查设备树和 U-Boot 配置。

6.4 测试脚本的编写与自动化

手动跑命令容易出错,建议写个脚本把测试流程固化下来:

#!/bin/bash # storage_bench.sh - iMX8 存储性能测试脚本 TEST_DIR=$1 SIZE=${2:-512M} if [ -z "$TEST_DIR" ]; then echo "用法: $0 <测试目录> [测试大小]" exit 1 fi echo "=== 清理缓存 ===" sync echo 3 > /proc/sys/vm/drop_caches echo "=== 顺序写测试 ===" fio --name=seqwrite --filename=$TEST_DIR/fio_test --rw=write \ --bs=1M --size=$SIZE --ioengine=libaio --direct=1 \ --group_reporting 2>&1 | grep -E "WRITE|bw=" echo "=== 顺序读测试 ===" fio --name=seqread --filename=$TEST_DIR/fio_test --rw=read \ --bs=1M --size=$SIZE --ioengine=libaio --direct=1 \ --group_reporting 2>&1 | grep -E "READ|bw=" echo "=== 4K 随机读测试 ===" fio --name=randread --filename=$TEST_DIR/fio_test --rw=randread \ --bs=4k --size=128M --numjobs=4 --iodepth=64 \ --ioengine=libaio --direct=1 --group_reporting 2>&1 | grep -E "READ|bw=" echo "=== 4K 随机写测试 ===" fio --name=randwrite --filename=$TEST_DIR/fio_test --rw=randwrite \ --bs=4k --size=128M --numjobs=4 --iodepth=64 \ --ioengine=libaio --direct=1 --group_reporting 2>&1 | grep -E "WRITE|bw=" rm -f $TEST_DIR/fio_test echo "=== 测试完成 ==="

这个脚本把常用测试串起来,输出只保留关键带宽数据,方便快速对比。实际项目中可以加上温度记录、多次取平均、结果写入 CSV 等功能。

7. 把测试结果转化为可落地的判断

测完一堆数据,最终要回答的问题是:这块板子的存储性能能不能满足我的应用需求。我的经验是,不要只看峰值数字,要看最差情况下的表现。比如视频录制应用,关注的是持续写入 30 分钟后的稳定带宽,而不是前 10 秒的爆发速度。

另外,存储性能测试应该贯穿产品开发的全流程:选型阶段做对比测试,调试阶段做验证测试,量产前做抽检。每次测试的记录都要保留,形成基线数据,后续出问题时才有对比依据。

最后分享一个实用技巧:如果测试结果和预期差距很大,先别急着怀疑硬件,用iostat -x 1看看 IO 等待和队列情况,用perf top看看有没有内核态的热点,很多时候问题出在软件配置而不是硬件本身。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询