当前位置: 首页 > news >正文

嵌入式Linux USB存储性能测试:从工具使用到瓶颈分析

1. 项目概述:为什么我们要关注U盘读写速度?

最近在调试一块瑞萨RZ/G2UL的工控板,项目里有个需求,需要频繁地从U盘里读取配置文件和写入日志数据。一开始没太在意,随便找了个U盘插上,结果发现拷贝一个几十兆的固件包,进度条走得慢吞吞,日志写入时系统偶尔还会“卡”一下。这让我意识到,在嵌入式Linux系统里,外存储器的性能绝不是小事,它直接关系到用户体验和系统响应的流畅度。

U盘,或者说USB Mass Storage设备,是我们和嵌入式设备交换数据最常用的桥梁之一。它的读写速度,受限于主控芯片的USB控制器性能、Linux内核的驱动栈效率、文件系统的选择,乃至U盘本身的主控和闪存品质。进行一次全面的速度测试,不是为了跑个分好看,而是为了摸清这套硬件平台数据吞吐能力的“底”,为后续的应用程序设计(比如该用多大的缓冲区、是否需要多线程读写)和系统优化(比如该用ext4还是F2FS)提供实实在在的数据支撑。如果你也在用类似的ARM工控板做产品,或者单纯好奇自己板子的USB性能到底如何,那跟着我一起操作一遍,肯定能有收获。

2. 测试环境与核心工具准备

2.1 硬件平台:瑞萨RZ/G2UL核心板详解

我手头这块板子是瑞萨RZ/G2UL系列的一款典型工业级核心板。G2UL是瑞萨“RZ/G2”家族中的入门款,主打高性价比和低功耗,但该有的接口一点没少。它集成了两个Cortex-A55内核(主频最高1.2GHz)和一个Cortex-M33实时核,我们今天关注的是它的USB 2.0 Host接口。

这里有个关键点:RZ/G2UL的USB接口是2.0标准的。理论上,USB 2.0的最高传输速率是480 Mbps(即60 MB/s),但这是物理层的理论值,实际传输数据时,要扣除协议开销、总线竞争等,能达到35-40 MB/s的持续读写就已经是非常好的成绩了。所以,我们的测试预期也要建立在这个基础上,如果测出来速度远低于这个值,那就需要排查问题了。

测试用的U盘我准备了三个,覆盖不同档次:

  1. 一个某品牌“高速”USB 3.0 U盘(标称读取100MB/s,写入20MB/s)。在USB 2.0接口上,它的速度会被限制在2.0的标准内,但好的主控和颗粒在2.0下通常也能跑满。
  2. 一个老旧USB 2.0 U盘(无标称速度),作为“地板”参考。
  3. 一个USB 3.0的移动固态硬盘(SSD),用于测试板子USB接口驱动大电流设备的能力和极限性能。

2.2 软件工具链:从系统命令到专业工具

测试在板子运行的Linux系统上进行,系统是使用Yocto项目定制的。测试不需要复杂的GUI,全部在终端下完成。核心工具如下:

  • lsusb:查看U盘是否被正确识别,以及其连接的USB速度模式(是USB 2.0还是意外降到了USB 1.1)。
  • dmesg:在插入U盘后,查看内核打印的详细信息,包括识别到的设备型号、分配的设备节点(如/dev/sda1),以及是否有错误信息。
  • hdparm:一个传统的磁盘性能测试工具,主要用于测试缓冲读取速度。它直接对设备进行读取,绕过了文件系统缓存,能反映磁盘硬件的最大读取能力。
  • dd:Linux下的“数据复制”瑞士军刀。我们将用它进行最原始、最直接的顺序读写测试。通过改变块大小(bs参数),可以观察不同I/O单元对速度的影响。
  • fio:专业级的弹性I/O测试工具。这是本次测试的重头戏。dd只能测试顺序读写,而真实场景可能是随机读写、混合读写。fio可以高度定制化测试模式,给出更全面的性能画像。

注意:使用ddfio进行写测试时,务必指定正确的设备或文件路径,并再三确认,否则有覆盖系统磁盘、导致数据丢失的风险!建议先在U盘上创建一个专门的测试文件进行写测试。

3. 测试执行与核心环节实现

3.1 前置检查:确保U盘以最佳状态连接

插入U盘后,第一步不是急着跑分,而是先做健康检查。

# 1. 查看U盘设备节点 $ dmesg | tail -20 ... [ 1234.567890] usb 1-1.1: new high-speed USB device number 5 using xhci-hcd [ 1234.678901] usb-storage 1-1.1:1.0: USB Mass Storage device detected [ 1234.690123] scsi host0: usb-storage 1-1.1:1.0 [ 1235.701234] scsi 0:0:0:0: Direct-Access SanDisk Ultra Fit 1.00 PQ: 0 ANSI: 6 [ 1235.712345] sd 0:0:0:0: [sda] 60062500 512-byte logical blocks: (30.8 GB/28.7 GiB) [ 1235.723456] sd 0:0:0:0: [sda] Write Protect is off [ 1235.734567] sd 0:0:0:0: Attached scsi generic sg0 type 0 [ 1235.745678] sd 0:0:0:0: [sda] Attached SCSI removable disk

可以看到,系统识别到了U盘,并分配了设备节点sda。同时,new high-speed USB device表明它以USB 2.0高速模式连接,这是好的开始。如果这里显示full-speed,那速度上限就只有12 Mbps了,需要检查USB线或接口。

# 2. 使用lsusb查看详情 $ lsusb -t /: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci-hcd/1p, 480M |__ Port 1: Dev 5, If 0, Class=Mass Storage, Driver=usb-storage, 480M

这里再次确认了设备运行在480M(即USB 2.0高速)模式下。

# 3. 挂载U盘并查看文件系统 $ sudo mount /dev/sda1 /mnt/usb $ df -Th /mnt/usb Filesystem Type Size Used Avail Use% Mounted on /dev/sda1 vfat 30G 1.2G 28G 4% /mnt/usb

我的U盘是FAT32格式。不同的文件系统(如ext4, NTFS, exFAT)由于其日志、块分配策略不同,性能会有差异,尤其是大量小文件读写时。本次测试为了控制变量,主要针对单个大文件进行。

3.2 基准测试:使用hdparm与dd获取初步数据

hdparm测试缓冲读取:

$ sudo hdparm -tT /dev/sda /dev/sda: Timing cached reads: 158 MB in 2.00 seconds = 78.87 MB/sec Timing buffered disk reads: 74 MB in 3.02 seconds = 24.52 MB/sec
  • -T测试的是从Linux页面缓存(Page Cache)中读取的速度,这基本是内存速度,用于验证系统总线和CPU性能,本例中78 MB/s对于A55内核来说正常。
  • -t测试的是从磁盘直接读取到内存的速度,这才是U盘的实际读取能力。24.52 MB/s,这个数字初步反映了该U盘在这块板子上的读取上限。不算快,但属于USB 2.0下的常见范围。

dd测试顺序读写:我们创建一个1GB大小的测试文件,并使用不同的块大小进行读写。

# 切换到U盘挂载点 $ cd /mnt/usb # 测试写入速度:从零设备(/dev/zero)读取数据,写入到测试文件 $ sudo dd if=/dev/zero of=./testfile bs=1M count=1024 oflag=direct,dsync 1024+0 records in 1024+0 records out 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 45.2362 s, 23.7 MB/s # 测试读取速度:从测试文件读取,写入到空设备(/dev/null) $ sudo dd if=./testfile of=/dev/null bs=1M count=1024 iflag=direct 1024+0 records in 1024+0 records out 1073741824 bytes (1.1 GB, 1.0 GiB) copied, 38.1129 s, 28.2 MB/s
  • oflag=direct,dsync:对于写测试,direct标志绕过系统缓存,dsync确保数据真正写入物理介质后才返回,这能测出最“真实”的写入速度。23.7 MB/s。
  • iflag=direct:对于读测试,direct绕过缓存,测出真实的读取速度。28.2 MB/s。
  • 块大小(bs)的影响bs=1M是比较大的块。如果换成bs=4k(模拟小文件读写),速度会急剧下降,可能只有几MB/s甚至几百KB/s。这是因为每次I/O操作都有固定开销,小块会导致开销占比过大。

实操心得dd测试简单直观,但有几个坑。第一,测试文件大小最好远大于系统内存,否则读测试可能测的是缓存速度。第二,dsync模式下的写速度会非常慢,因为它要求每次写操作都同步到磁盘,实际应用程序很少这么用。更常见的模式是使用oflag=direct但不加dsync,或者什么都不加(使用缓存),后者速度会快很多,但反映的是“缓存写入速度”。

3.3 专业测试:使用fio进行全面压力测试

fio才是揭示真相的工具。我们编写一个fio任务配置文件usb_test.fio

[global] ioengine=libaio # 使用异步I/O引擎,效率更高 direct=1 # 绕过系统缓存,直写设备 size=1G # 每个线程测试文件大小 runtime=60 # 每个测试运行60秒 directory=/mnt/usb # 测试目录 filename_format=fio_test.$jobname [seq-read] name=顺序读取测试 rw=read bs=1M numjobs=1 [seq-write] name=顺序写入测试 rw=write bs=1M numjobs=1 [rand-read-4k] name=4K随机读取测试 rw=randread bs=4k numjobs=4 # 4个线程并发,模拟多任务压力 iodepth=16 # I/O队列深度为16 [rand-write-4k] name=4K随机写入测试 rw=randwrite bs=4k numjobs=4 iodepth=16 [mixed-io] name=混合读写测试(70%读/30%写) rw=randrw rwmixread=70 bs=4k numjobs=4 iodepth=16

然后运行测试:

$ fio usb_test.fio

等待测试完成后,fio会输出一份详细的报告。我们重点关注以下几个结果:

  • 顺序读写(seq-read/seq-write):结果应与dd测试接近,作为相互验证。例如,seq-writebw(带宽)可能在 22-25 MB/s 左右。
  • 4K随机读写(rand-read-4k / rand-write-4k):这是对U盘(尤其是TLC闪存)和USB协议栈的严峻考验。报告中的iops(每秒I/O操作次数)是关键指标。一个普通的USB 2.0 U盘,4K随机写入的iops可能只有几百。这个指标直接决定了系统在频繁写入小文件(如日志)时的流畅度。
  • 混合读写(mixed-io):最贴近真实场景。观察此时的带宽和iops,以及读写延迟(lat)的分布。如果延迟的clat(完成延迟)的mean(平均值)很高,或者99.00%分位的值非常大(例如超过500毫秒),说明在压力下响应很不稳定,容易引起卡顿。

在我的测试中,那个“高速”USB 3.0 U盘在G2UL的USB 2.0接口上,测出了如下典型数据:

  • 顺序读取:~32 MB/s
  • 顺序写入:~21 MB/s
  • 4K随机读取IOPS:~2800
  • 4K随机写入IOPS:~350
  • 混合读写(70/30)平均延迟:读 ~5ms, 写 ~120ms

而那个老旧U盘的4K随机写入IOPS只有不到100,混合写延迟经常飙到500ms以上,这也就解释了为什么系统会感觉“卡”。

4. 结果分析与性能瓶颈深度剖析

4.1 数据解读:从数字看到系统行为

将三个U盘的测试数据整理成表格,对比非常明显:

测试项目“高速”USB3.0 U盘老旧USB2.0 U盘USB3.0 移动SSD
顺序读取 (MB/s)32.118.539.8(接近2.0极限)
顺序写入 (MB/s)21.76.234.5
4K随机读 IOPS28504506800
4K随机写 IOPS350851500
混合读写平均写延迟~120ms>500ms~25ms

分析结论:

  1. 接口瓶颈:移动SSD的顺序读写速度明显高于普通U盘,且接近USB 2.0的物理极限(~40 MB/s),这说明G2UL的USB 2.0 Host控制器驱动和硬件本身是没问题的,性能瓶颈主要在U盘自身的闪存和主控上。
  2. 随机性能天差地别:4K随机写入IOPS是衡量“是否卡顿”的关键。老旧U盘的85 IOPS意味着每秒只能完成85次4K写入,在频繁写日志时队列很容易积压,导致进程阻塞。而移动SSD的1500 IOPS则从容得多。
  3. 延迟稳定性:混合读写测试中,移动SSD的写延迟远低于U盘,且99%分位延迟也控制得很好,说明其主控的垃圾回收和磨损均衡算法更高效,能提供更稳定的性能。

4.2 瓶颈定位与优化思路探讨

基于测试,我们可以从多个层面思考优化:

1. 硬件选型建议:

  • 对于关键数据存储:如果项目对数据写入速度、尤其是小文件写入的流畅性有要求,强烈建议选择品质较好的USB 3.0 U盘或直接使用移动SSD。虽然接口是2.0,但好的主控和颗粒在2.0下的随机性能也远超低端U盘。注意检查板子的USB口供电是否充足,移动SSD功耗较大。
  • 考虑eMMC或SD卡:对于固定在设备上的存储,板载的eMMC或高速SD卡(通过SDIO接口)的性能通常远优于USB 2.0 + U盘的组合,延迟更低,可靠性也更高。

2. 软件与系统层面优化:

  • 文件系统选择:FAT32/exFAT兼容性好,但无日志,掉电易损,且小文件性能一般。如果U盘专用于此设备,可格式化为ext4(带日志,数据更安全,性能较好)或F2FS(专为闪存设计,尤其在小文件随机写入上有时比ext4更有优势)。测试对比一下会有惊喜。
  • 挂载参数优化:在/etc/fstab中为U盘添加优化挂载选项。例如,对于ext4,可以尝试noatime,nodiratime,data=writebacknoatime可以避免每次读操作都更新文件访问时间元数据,减少不必要的写入。
  • 应用程序设计
    • 缓冲写入:避免频繁的、直接调用write()进行小块写入。应在应用层积累一定数据后(如4KB或更大)再一次性写入。
    • 异步I/O:对于日志等非实时性要求极高的写入,可以使用异步I/O或单独的写入线程,避免阻塞主线程。
    • 调整日志级别和策略:若非必要,降低日志生成频率,或采用循环日志、按大小分割日志文件,避免单个文件过大。

5. 常见问题与排查技巧实录

在实际测试和后续开发中,我遇到了不少问题,这里总结几个典型的:

问题1:dd测试写入速度超级快(超过100 MB/s),明显不正常。

  • 现象dd if=/dev/zero of=./testfile bs=1M count=1024命令瞬间完成,显示速度几百MB/s。
  • 原因:数据只写入了Linux的系统缓存(Page Cache),并没有真正落到U盘上。系统会在后台异步刷入磁盘。
  • 排查与解决:使用oflag=direct,dsync参数进行测试,这才是真实的写入速度。或者,在测试后执行sync命令强制刷盘,再观察实际耗时。

问题2:U盘突然变成只读(read-only)文件系统。

  • 现象:写入文件时提示“Read-only file system”。
  • 原因:可能是文件系统错误(如FAT32的脏位)、USB接口接触不良导致数据传输错误、或U盘本身进入保护状态。
  • 排查
    1. 运行dmesg | tail查看内核是否有相关错误报告(如I/O error)。
    2. 尝试重新拔插U盘。
    3. 在Windows或Linux桌面系统上检查并修复U盘文件系统。
    4. 如果问题频繁出现,考虑更换U盘或USB线缆,可能是硬件不稳定。

问题3:fio测试时,随机写入的IOPS极低(个位数),且延迟巨大。

  • 现象:4K随机写入测试带宽只有几十KB/s,iops是个位数,延迟上万毫秒。
  • 原因:U盘主控正在疯狂进行垃圾回收。特别是那些容量快满的、或使用TLC/QLC闪存的低端U盘,在持续随机写入时,主控需要先擦除块再写入,性能会雪崩。
  • 解决
    1. 预留空间:不要将U盘塞满,保留至少10%-20%的剩余空间,给主控进行垃圾回收和磨损均衡用。
    2. 全盘擦除/安全擦除:如果条件允许,在PC上用工具对U盘进行全盘擦除,可以恢复一部分性能(但治标不治本)。
    3. 终极方案:换用性能更好的存储介质。

问题4:测试结果波动很大,每次运行差异明显。

  • 原因:后台可能有其他进程在访问U盘(如系统日志、桌面环境索引);或者U盘本身温度升高导致主控降速;亦或是USB总线被其他设备(如USB网卡)干扰。
  • 排查
    1. 测试前,使用iotoppidstat -d命令查看是否有其他进程在对测试目录进行磁盘I/O。
    2. 尽量在空闲的系统上进行测试,关闭不必要的服务。
    3. 确保U盘插在独立的USB端口上,避免与高带宽设备共享总线。

经过这一轮从工具使用到原理分析,再到问题排查的完整流程,你应该对如何评估嵌入式系统的USB存储性能有了清晰的认识。性能测试不是跑个分就完了,关键是通过数据理解系统的行为边界,从而在硬件选型、系统配置和软件设计上做出更明智的决策。对于这块瑞萨G2UL板子,结论就是:它的USB 2.0接口性能达标,但要想获得流畅的存储体验,配上一个好点的U盘或直接使用板载存储,是非常有必要的。

http://www.jsqmd.com/news/817676/

相关文章:

  • 包头招聘软件哪个靠谱:秒聘网靠谱专业 - 13425704091
  • 安卓本地AI助手部署:基于GlibClaw与Magisk模块的离线解决方案
  • 英语阅读_GARDEN CITY COLLEGE
  • 轨道交通实时数据可视化平台架构:从流处理到WebGL渲染的工程实践
  • 2026年Q2浙江小单/个性化/高端/商务/定制袜子可靠厂家综合分析与指南 - 2026年企业推荐榜
  • PFXA401SF控制器
  • 井漏压力波特征辨识理论方法【附代码】
  • 包头招聘网站哪个好:秒聘网首位优选 - 19120507004
  • 避坑指南:树莓派USB摄像头识别出两个video设备怎么办?实测罗技免驱摄像头
  • 烽火服务器IPMI远程终端报JNLP错误?别慌,Java环境配置与权限检查保姆级指南
  • STM32WLE5CCU6移植官方PingPong例程实战:从CubeMX导入到E77模块适配的完整流程
  • 后摩尔时代芯粒与先进封装:芯片设计新范式与测试挑战
  • 2025届学术党必备的十大AI辅助论文平台实测分析
  • 保定招聘网站哪个岗位多:秒聘网海量职岗 - 17322238651
  • 基于ROS与LLM的智能体协作框架:从架构设计到实战部署
  • 豆包“扫一扫”或支持支付订单,字节借“AI+支付”完善生态、扩大市场份额?
  • 时钟同步技术中的滤波与拥塞标记原理详解
  • 别再死记硬背了!用这5个高频场景吃透华为eNSP基础命令(含时间修改、密码配置)
  • 别再乱用String当密钥了!jjwt 0.10+版本的正确使用姿势与JDK兼容性避坑指南
  • vue基于springboot框架的基于协同过滤算法的音乐推荐系统
  • 汽车VIT测试十年进化:从整车功能检查到全域智能验证体系
  • 别只盯着算法!聊聊搭建五子棋机器人时,那些容易被忽略的‘硬件’细节:从机械臂选型到棋盘照明
  • 观察同一任务在不同模型间切换时的响应速度与结果一致性
  • 保定招聘网站推荐:秒聘网省心求职 - 19120507004
  • 2026更新文昌火箭观礼门票服务商挑选参考及常见服务内容梳理 - 热敏感科技蜂
  • EtherCAT状态机实战解析:从INIT到OP的配置与排错指南
  • RFSoC技术在低电平射频控制系统中的创新应用
  • 少儿AI英语阅读APP的开发
  • 包头招聘软件哪个好:秒聘网顶尖平台 - 17329971652
  • 动态知识图谱构建:从本体论到工程实践