第四章:压力测试——CPU/GPU满载测试、内存压力测试、IO吞吐测试

各位好,我是老张。今天咱们聊聊压力测试。

说实话,座舱系统最怕什么?不是功能少,而是用着用着就卡死、黑屏、重启。我见过太多项目,功能演示时一切完美,一到用户手里就崩。为什么?说白了,就是没扛住压力。

这一章,我带你走一遍MTK8678的压力测试全流程。CPU/GPU满载、内存压力、IO吞吐,这三板斧砍下去,系统稳不稳,立马见分晓。

4.1 CPU/GPU满载测试——让芯片跑到冒烟

CPU满载测试,不是简单跑个分就完事。我习惯的做法是:让所有核心同时跑满,持续至少30分钟,同时监测温度、频率、电压。

核心目标:验证SoC在持续高负载下,是否触发降频、关机、或出现计算错误。

4.1.1 CPU满载测试方法

MTK8678是8核架构,4个A78大核+4个A55小核。我建议分两步走:

  1. 全核满载:所有核心同时跑100%负载
  2. 大小核分离:只压大核或只压小核,看调度策略

工具方面,我推荐用stress或者自己写个死循环脚本。下面是我常用的测试脚本:

#!/system/bin/sh
# CPU满载测试脚本 - 适用于MTK8678

echo "开始CPU满载测试..."

# 启动8个线程,每个核心一个
for i in $(seq 1 8); do
    stress --cpu 1 --timeout 1800 &
done

echo "所有核心已满载,持续30分钟..."

# 实时监控频率和温度
while true; do
    cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq
    cat /sys/class/thermal/thermal_zone*/temp
    sleep 5
done

我在项目中遇到过一个问题:跑满负载后,系统温度飙到85°C,然后突然降频到1.2GHz。嗯,这其实是正常的保护机制。但关键要看——降频后系统还能不能稳定运行?有没有出现ANR?

我的小技巧:测试时同时开个logcat,抓取thermalpower相关的日志。这样能清楚看到降频的触发点和恢复时机。

4.1.2 GPU满载测试

GPU测试比CPU更讲究。MTK8678用的是Mali-G610 MC3,3个核心。我建议用glmark2或者GFXBench这类工具。

但说实话,跑分工具只能测个大概。我更推荐的做法是:

  • 同时播放4路1080P视频
  • 叠加3D导航动画
  • 再开一个高帧率游戏

这才是座舱的真实场景。你想想看,用户开车时,导航、音乐、倒车影像、语音助手可能同时在工作。GPU扛不住,画面就会撕裂、掉帧。

注意:GPU满载时,别忘了监测/sys/class/kgsl/kgsl-3d0/gpu_busy_percentage。如果这个值长期低于80%,说明你的测试负载不够重。

4.2 内存压力测试——别让OOM killer找上门

内存压力测试,说白了就是看系统在内存吃紧时,能不能优雅地处理。我最怕的一种情况是:内存泄漏慢慢积累,用户用了一周后突然卡死。

4.2.1 内存压力测试方法

我常用的工具是memtesterstressapptest。但更贴近实际的做法是:

  1. 逐步分配内存,直到系统剩余内存低于100MB
  2. 观察系统是否触发lowmemorykiller
  3. 检查被杀的进程是不是关键服务
#!/system/bin/sh
# 内存压力测试脚本

echo "开始内存压力测试..."

# 逐步分配内存,每次分配100MB
total=0
while [ $total -lt 3500 ]; do
    stress --vm 1 --vm-bytes 100M --timeout 60 &
    total=$((total + 100))
    echo "已分配: ${total}MB"
    sleep 2
    
    # 检查系统剩余内存
    free_mem=$(cat /proc/meminfo | grep MemAvailable | awk '{print $2}')
    if [ $free_mem -lt 102400 ]; then
        echo "警告:剩余内存不足100MB!"
        break
    fi
done

echo "内存压力测试完成"

我曾经在一个项目里发现,内存压力测试时,系统的Launcher被lowmemorykiller给杀了。这问题很严重——用户正开着导航呢,突然桌面重启了,你说吓不吓人?

关键检查点:确保/proc/zoneinfo中的lowmin水位线设置合理。MTK8678通常建议保留至少200MB的可用内存给前台进程。

4.2.2 内存泄漏检测

压力测试不只是看瞬间表现。我习惯做长时间的内存泄漏测试:

  • 反复打开/关闭所有预装应用,持续12小时
  • 每次操作后记录/proc/meminfoMemAvailable
  • 如果可用内存持续下降,说明有泄漏

我的经验:dumpsys meminfo可以看每个进程的内存占用。重点关注system_serversurfaceflinger,这两个最容易泄漏。

4.3 IO吞吐测试——别让存储拖后腿

IO性能,很多人容易忽略。但座舱系统里,导航地图加载、音乐播放、行车记录仪写入,全都依赖IO。IO慢,整个系统就像卡住了一样。

4.3.1 IO吞吐测试方法

MTK8678用的是UFS 2.2或3.0。我建议用fio工具做测试:

# 顺序读测试
fio --name=seq_read --ioengine=sync --rw=read --bs=1M --size=1G --numjobs=1 --runtime=60

# 随机写测试
fio --name=rand_write --ioengine=sync --rw=randwrite --bs=4K --size=1G --numjobs=4 --runtime=60

# 混合读写测试
fio --name=mix_rw --ioengine=sync --rw=randrw --rwmixread=70 --bs=4K --size=1G --numjobs=4 --runtime=120

我一般关注三个指标:

测试项 期望值(UFS 2.2) 期望值(UFS 3.0)
顺序读 > 800 MB/s > 1500 MB/s
顺序写 > 400 MB/s > 800 MB/s
随机读(4K) > 20000 IOPS > 40000 IOPS
随机写(4K) > 15000 IOPS > 30000 IOPS

注意:IO测试时,一定要在系统负载较高的情况下做。我试过空载时IO性能很好,但一旦CPU满载,IO吞吐直接掉了一半。这就是所谓的「IO干扰」问题。

4.3.2 并发IO场景测试

座舱系统里,IO往往是并发的。我模拟过这样的场景:

  • 后台下载地图数据(持续写)
  • 同时播放本地音乐(持续读)
  • 行车记录仪写入视频(持续写)
  • 导航加载路况信息(随机读)

这种混合场景下,IO延迟会明显增加。我建议用iostat监控awaitsvctm。如果await超过100ms,用户就能感知到卡顿了。

我的判断标准:在并发IO场景下,await应小于50ms,%util不应长期超过90%。否则,存储子系统就是瓶颈。

4.4 综合压力测试——三板斧一起上

单独测CPU、内存、IO还不够。真正的考验是三者同时满载。我称之为「地狱模式」:

  1. CPU 8核全满载
  2. GPU跑高负载渲染
  3. 内存分配到剩余100MB
  4. IO持续随机读写

这种场景下,系统还能不能流畅运行?会不会触发看门狗重启?我见过不少项目,单测都没问题,一上综合压力就崩。

我的建议:综合压力测试至少跑2小时。前30分钟看性能,后90分钟看稳定性。很多问题是在持续负载30分钟后才暴露出来的。

4.5 常见问题与排查思路

最后,我总结几个我在项目中踩过的坑:

  • CPU降频太激进:温度刚到75°C就降频到1.0GHz。解决方案是调整thermal-engine.conf中的温控阈值。
  • OOM killer误杀:把系统UI进程给杀了。需要在/proc/pid/oom_adj中设置关键进程的优先级。
  • IO饥饿:某个进程占用了大量IO,导致其他进程等待。用iotop可以找到罪魁祸首。

嗯,这一章的内容就到这里。压力测试不是走过场,它是座舱系统稳定性的最后一道防线。你想想看,用户开车时系统崩了,那可不是小事。所以,该压的压,该测的测,别偷懒。

下一章,咱们聊聊长时间稳定性测试和异常恢复机制。到时候见。


公众号:蓝海资料掘金营,微信deep3321