2. Simulink控制模型性能评估指标体系
在Simulink中完成一个控制模型之后,真正决定它能否用于工程交付的,往往不是“功能是否跑通”,而是“性能是否达标”。性能评估不是单一指标的打分,而是一组相互制约的指标集合:仿真速度决定迭代效率,实时性决定能否上目标机,精度决定结果可信度,稳定性决定长时间运行是否可靠,代码生成效率决定从模型到嵌入式代码的落地成本,资源占用决定目标硬件的可行性。理解这些指标的定义、测量位置和相互影响,是后续优化的前提。
一、六类关键指标的定义与测量位置
仿真速度通常用“仿真时间/墙钟时间”的比值来衡量,即 Simulation Time / Wall-Clock Time。例如一个10秒的仿真在2秒内跑完,比值为5,表示比实时快5倍。测量时应固定求解器、步长、模型配置,只改变待评估对象,否则数据不可比。Simulink中可通过 Simulink.BlockDiagram.getSimulationMetadata 或仿真结束后查看 SimulationMetadata.TimingInfo 获取总执行时间,也可用 tic/toc 包裹 sim 命令做端到端测量。
实时性关注的是模型在目标硬件上能否在每个采样周期内完成一次计算。核心指标是“单步执行时间”与“采样周期”的比值,通常要求小于0.7~0.8,留出余量。测量方法是在目标机或Simulink Real-Time环境中记录每个步长的执行时间,观察最坏情况执行时间(WCET)。若单步执行时间超过采样周期,就会出现超时(overrun),实时性不达标。
精度指标反映仿真结果与参考结果之间的偏差。常用定义包括绝对误差、相对误差和均方根误差(RMSE)。测量时先建立高精度参考(如小步长定步长或变步长高精度求解器),再与待评估配置的结果逐点比较。例如对同一控制模型,用 ode45 小步长作为参考,比较 ode4 在1ms步长下的输出偏差,若RMSE超过设定阈值(如0.5%),则精度不满足要求。
稳定性指标衡量模型在长时间运行或参数扰动下是否发散、振荡或出现数值异常。测量方法包括:长时间仿真观察输出是否收敛;对关键参数施加±10%扰动,观察系统是否仍保持有界;检查求解器是否频繁报错或步长被压缩到极小值。稳定性不达标通常表现为输出持续增大、高频振荡或仿真中断。
代码生成效率关注从模型生成嵌入式代码的耗时、代码体积和可读性。测量指标包括生成时间、生成代码行数、ROM/RAM占用估算。在Simulink中可通过 slbuild 或 Embedded Coder 的代码生成报告获取这些数据。例如同一模型在不同配置下生成代码,比较生成时间和代码体积,判断优化效果。
资源占用指标包括CPU占用率、内存占用、栈深度和任务调度开销。在目标机上可通过性能计数器或RTOS提供的任务统计接口测量。例如在STM32平台上,通过DWT周期计数器测量单步执行周期数,通过链接器映射文件查看RAM/Flash占用。
二、指标之间的制约关系
这六类指标并非独立,而是存在明显的制约关系。最典型的是“精度—速度”矛盾:减小步长或选用高阶求解器可以提高精度,但会显著降低仿真速度。例如将定步长从1ms减小到0.1ms,仿真速度可能下降近10倍。因此评估时必须明确当前阶段的核心目标:若用于控制算法迭代,优先保证仿真速度;若用于结果验证,优先保证精度。
“实时性—资源占用”同样相互制约。提高实时性通常需要简化模型或降低计算量,这会减少资源占用,但可能牺牲精度。反之,追求高精度会增大计算量,导致单步执行时间增加,实时性下降。在嵌入式部署中,通常需要在实时性和精度之间找到平衡点,例如通过定点化、查表法或降阶来降低计算量。
“代码生成效率—可读性”也存在权衡。开启高度优化选项(如内联、循环展开)可以减小代码体积、提高执行效率,但生成代码的可读性和可调试性会下降。评估时应根据交付要求选择:若需要人工审查代码,应保留可读性;若只关注运行效率,可开启激进优化。
三、测量方法与操作示例
下面给出一个可复用的测量流程示例。假设有一个电机控制模型 MotorCtrl.slx,采样周期为1ms,需要评估其仿真速度和实时性。
% 1. 仿真速度测量
model = 'MotorCtrl';
load_system(model);
set_param(model, 'Solver', 'ode4', 'FixedStep', '0.001');
tic;
simOut = sim(model, 'StopTime', '10');
elapsed = toc;
speedRatio = 10 / elapsed;
fprintf('仿真速度比: %.2f\n', speedRatio);
% 2. 实时性测量(目标机)
% 在Simulink Real-Time中启用执行时间记录
set_param(model, 'RTWVerbose', 'on');
% 运行后查看 overrun 计数和执行时间直方图
对于精度测量,可先建立参考结果:用 ode45 变步长、相对容差 1e-6 运行一次,保存输出。再切换到待评估配置运行,计算RMSE:
ref = simOut_ref.y;
test = simOut_test.y;
rmse = sqrt(mean((ref - test).^2));
relErr = rmse / (max(ref) - min(ref));
fprintf('相对RMSE: %.4f%%\n', relErr * 100);
对于资源占用,在STM32目标上可通过DWT计数器测量单步执行周期数:
// 在步进函数入口和出口读取DWT->CYCCNT
uint32_t start = DWT->CYCCNT;
MotorCtrl_step();
uint32_t cycles = DWT->CYCCNT - start;
// 若主频为168MHz,采样周期1ms对应168000周期
// 占用率 = cycles / 168000
四、评估结果判读与优化方向
测量完成后,需要根据工程目标判读结果。若仿真速度比低于1,说明仿真比实时还慢,需要检查是否有代数环、过小步长或频繁触发的零 crossings。若实时性占用率超过80%,应优先考虑模型简化、定点化或任务拆分。若精度RMSE超过1%,应检查求解器选择、步长和数值精度设置。若代码体积超出Flash容量,应检查是否有冗余模块、未使用的信号或可合并的运算。
需要强调的是,性能评估不是一次性的,而应贯穿模型开发全过程。在算法设计阶段关注仿真速度和精度,在部署阶段关注实时性和资源占用,在交付阶段关注代码生成效率和稳定性。只有把六类指标放在同一套评估框架下持续跟踪,才能避免“功能通过但性能不达标”的返工。