4. 生成高效代码的优化设置

任务定义

本案例目标:在Embedded Coder中配置代码生成优化选项,使生成的C代码在保持功能正确的前提下,减少RAM/ROM占用并提升执行效率。完成从模型配置、代码生成到优化效果验证的完整闭环。

模型准备

使用Simulink建立一个简单的二阶低通滤波器模型作为优化对象。该模型包含两个单位延迟单元、四个增益模块和两个求和模块,采样时间设为0.01s。模型输入为正弦波信号源,输出连接至Scope模块以便仿真验证。

二阶低通滤波器模型结构 Inport Gain1 Gain2 Sum1 Gain3 Outport UnitDelay1 UnitDelay2 Gain4

优化配置步骤

在Simulink模型中打开模型配置参数对话框,依次完成以下优化设置:

1. Solver设置:选择离散求解器,固定步长设为0.01,确保生成的代码为纯离散算法,不包含连续求解器相关代码。

2. 代码生成-优化面板:勾选以下关键选项:

  • 模块复用:允许共享相同表达式,减少重复计算;
  • 局部变量复用:使能局部变量重用,降低栈空间需求;
  • 表达式折叠:将中间表达式合并为单条语句,减少临时变量;
  • 内联不变信号:将循环不变计算移出循环体。

3. 代码生成-接口面板:将代码接口打包设为可重用函数,生成独立的函数接口便于集成。

生成代码与关键实现

完成配置后,使用Ctrl+B生成C代码。核心算法代码位于step函数中,优化后的实现如下:

/* 模型步进函数 - 优化后版本 */
void filter_step(void)
{
  /* 局部变量声明(复用优化后仅需2个临时变量) */
  real_T rtb_sum1;
  real_T rtb_sum2;

  /* Sum: '<S1>/Sum1' 包含增益合并优化 */
  rtb_sum1 = (0.1 * filter_U.In1) + (0.5 * filter_DW.UnitDelay1_DSTATE);

  /* Sum: '<S1>/Sum2' 表达式折叠后直接计算 */
  rtb_sum2 = rtb_sum1 + (0.3 * filter_DW.UnitDelay2_DSTATE);

  /* 状态更新:单次赋值完成两个延迟单元更新 */
  filter_DW.UnitDelay2_DSTATE = filter_DW.UnitDelay1_DSTATE;
  filter_DW.UnitDelay1_DSTATE = rtb_sum1;

  /* 输出赋值 */
  filter_Y.Out1 = rtb_sum2;
}

该代码体现了三项核心优化:增益系数0.1、0.5、0.3直接合并到求和运算中,消除了独立的乘法操作;中间结果通过两个局部变量复用,避免了额外的全局变量;状态更新采用顺序赋值,减少了内存访问次数。

验证方法与判定标准

功能验证:在Simulink中运行仿真,记录Scope输出波形。然后使用生成的C代码在MATLAB中通过coder.extrinsic或编译为MEX文件进行验证,对比模型仿真输出与生成代码输出。判定标准:两者最大误差小于1e-6。

优化效果验证:在代码生成报告中查看以下指标:

  • RAM使用量:优化后应小于未优化配置的80%;
  • ROM(代码大小):优化后应小于未优化配置的85%;
  • 最大堆栈深度:通过静态分析工具确认不超过256字节。

执行效率验证:在目标硬件(如STM32F407)上运行生成的代码,使用定时器测量单次step函数执行时间。判定标准:执行时间应小于采样周期0.01s的10%,即1ms以内。

对比测试方法

为量化优化效果,创建两份配置副本:一份使用默认优化级别(优化=无),另一份使用上述优化设置。分别生成代码并对比:

/* 未优化版本片段(对比用) */
void filter_step(void)
{
  /* 每个增益独立计算,产生更多临时变量 */
  real_T tmp1 = 0.1 * filter_U.In1;
  real_T tmp2 = 0.5 * filter_DW.UnitDelay1_DSTATE;
  real_T tmp3 = tmp1 + tmp2;
  real_T tmp4 = 0.3 * filter_DW.UnitDelay2_DSTATE;
  real_T tmp5 = tmp3 + tmp4;
  filter_Y.Out1 = tmp5;
  filter_DW.UnitDelay2_DSTATE = filter_DW.UnitDelay1_DSTATE;
  filter_DW.UnitDelay1_DSTATE = tmp3;
}

通过对比两份代码的变量数量、语句行数以及编译后的汇编指令数,即可直观验证优化效果。判定标准:优化版本局部变量数减少40%以上,语句数减少30%以上。