2. 转码基础概念

性能调优这件事,说白了就是「先测量,再动手」。没有基准测试,你根本不知道自己的转码管线到底慢在哪里,优化之后到底有没有效果。我见过太多团队,上来就改参数、换库、调线程,忙活了一周,结果一问——「嗯,感觉好像快了一点?」。这不行。

这一章,我们就来聊聊怎么科学地做基准测试。我会把定义指标、选工具、建基线这三个步骤拆开讲,每个环节都带上我踩过的坑。

第一步:定义性能指标

你想想看,如果连「快」和「慢」的标准都没定好,你怎么判断优化有没有用?我个人习惯把指标分成三类:吞吐类、延迟类、资源类。

指标类别 典型指标 说明
吞吐类 FPS(帧/秒)、MB/s、任务数/小时 单位时间内能处理多少数据
延迟类 P50/P95/P99 延迟、首帧时间 单个任务从提交到完成花了多久
资源类 CPU 利用率、GPU 显存占用、内存峰值 硬件吃不吃得消,有没有瓶颈

核心原则:吞吐和延迟必须一起看。只看吞吐,可能把延迟搞炸了;只看延迟,可能浪费了硬件资源。我一般会先定一个「SLA 边界」,比如:在 1080p H.264 转 H.265 的场景下,FPS 不低于 30,P99 延迟不超过 5 秒。

嗯,这里要注意:指标不是越多越好。我见过有人列了二十多个指标,最后根本不知道看哪个。我个人建议,每个场景选 3-5 个核心指标就够了。比如直播转码,重点关注延迟和 FPS;离线批量转码,重点关注吞吐和资源利用率。

第二步:选择合适的基准测试工具

工具选不对,测试结果就是废的。我这些年用过不少工具,挑几个有代表性的说说。

FFmpeg 内置的 benchmark 模式

这是最直接的方式。FFmpeg 自带的 -benchmark 和 -benchmark_all 参数,可以输出编码耗时、帧率、比特率等信息。适合快速验证单个转码命令的性能。

ffmpeg -i input.mp4 -c:v libx264 -preset medium -benchmark -f null /dev/null

输出里会显示 real time、user time、max memory 等数据。不过要注意,这个模式只跑一次,结果波动可能很大。我建议至少跑 3 次取中位数。

GStreamer 的 perf 插件

如果你的管线是基于 GStreamer 的,可以用 perf 插件。它能统计每个元素的处理时间、丢帧率、缓冲区状态。我在项目中遇到过一个问题:某个 filter 元素处理速度跟不上,导致下游解码器频繁丢帧。用 perf 插件一查,问题一目了然。

gst-launch-1.0 filesrc location=input.mp4 ! qtdemux ! h264parse ! perf ! avdec_h264 ! videoconvert ! perf ! x264enc ! perf ! fakesink

专业压测工具:JMeter / Locust

如果你的转码管线是作为服务对外暴露的(比如 REST API 提交转码任务),那就要用压测工具模拟并发请求。JMeter 适合传统 HTTP 接口,Locust 更轻量、支持 Python 脚本。我个人更倾向 Locust,因为可以灵活控制用户行为模型。

小技巧:不要只用一种工具。我习惯用 FFmpeg benchmark 做单点验证,用 GStreamer perf 做管线内部分析,最后用 Locust 做端到端压测。三层验证下来,数据才靠谱。

第三步:建立性能基线

基线是什么?就是你的「参考零点」。没有基线,你优化后的 30 FPS 到底是好是坏?没人知道。建立基线有四个关键动作。

  1. 固定测试环境:硬件型号、驱动版本、操作系统、依赖库版本,全部锁死。我吃过一次亏:换了显卡驱动版本,转码性能直接掉了 15%,排查了两天才发现。
  2. 固定测试数据:准备一套标准测试素材,包含不同分辨率、码率、编码格式的样本。素材要足够大,至少能跑 30 秒以上,避免冷启动和缓存干扰。
  3. 多次运行取统计值:跑 5-10 次,去掉最高最低,取中位数或平均值。同时记录标准差,标准差太大说明系统不稳定,需要排查干扰因素。
  4. 记录完整上下文:把测试时间、环境信息、参数配置、原始数据全部记录下来。我习惯用 JSON 格式保存,方便后续对比。

避坑指南:我曾经在建立基线时忽略了「后台进程干扰」。测试机器上跑着日志采集、监控 agent,导致基线数据波动很大。后来我学乖了:测试前关掉所有非必要服务,用 taskset 绑定 CPU 核心,用 nice -n -20 提升进程优先级。

知识体系总览

下面这张图,把性能基准测试的核心逻辑串起来了。你可以把它当作本章的「思维导图」。

性能基准测试知识体系 性能基准测试知识体系 定义性能指标 选择基准测试工具 建立性能基线 吞吐类:FPS、MB/s 延迟类:P50/P95/P99 资源类:CPU/GPU/内存 FFmpeg benchmark GStreamer perf 插件 JMeter / Locust 固定测试环境 固定测试数据 多次运行取统计值 记录完整上下文 核心原则 • 吞吐与延迟必须同时关注,不能偏废 • 每个场景选 3-5 个核心指标,不要贪多 • 基线建立后,任何环境变更都要重新跑一遍

实战:一个完整的基线建立流程

光说不练假把式。我拿一个实际项目举例:某视频平台需要优化 H.264 转 H.265 的离线转码管线。我们当时是这样做的。

  1. 定指标:核心看 FPS 和 CPU 利用率,辅助看 P95 延迟和内存峰值。
  2. 选工具:用 FFmpeg benchmark 跑单命令,用 GStreamer perf 查管线内各环节耗时。
  3. 建基线:固定一台裸金属服务器(Intel Xeon Gold 6248R,NVIDIA T4),用同一段 5 分钟 4K 视频,跑 10 次取中位数。记录下基线值:FPS=28.3,CPU=72%,P95 延迟=4.2s。
  4. 验证稳定性:连续跑 3 天,每天跑一次基线,确认波动在 ±3% 以内。

关键提醒:基线不是建完就完事了。每次硬件升级、驱动更新、库版本变更,都要重新跑一遍基线。我见过有人半年前建的基线还在用,结果换了显卡驱动后性能变了,他还以为是优化有效果——其实是基线过期了。