MATLAB编码器生成代码中的优化

为了提高生成代码的执行速度和内存使用量,MATLAB®编码器™介绍以下优化:

常数合并

如果可能的话,代码生成器会对只涉及编译时常量的MATLAB代码中的表达式进行计算。在生成的代码中,它将这些表达式替换为计算的结果。这种行为被称为常数折叠。由于经常折叠,生成的代码不必在执行期间计算常量。

下面的例子展示了在代码生成期间经常折叠的MATLAB代码。这个函数MultiplyConstant将矩阵中的每个元素乘以一个标量常数。该函数使用三个编译时常量的乘积来计算该常量,一个b,c

函数= MultiplyConstant(中)% # codegen一个=π^ 4;b = 1 /阶乘(4);c = exp (1);出=。* (a * b * c);结束

代码生成器计算包含编译时常量的表达式,一个b,c.它用生成代码中的求值结果替换这些表达式。

当表达式只涉及标量时,可以发生常量折叠。要在其他情况下显式强制表达式的常量折叠,请使用coder.const函数。有关更多信息,请参见将函数调用折叠到常量中

控制常数合并

您可以从命令行或项目设置对话框中控制可常量折叠的指令的最大数量。

  • 在命令行中,创建一个用于代码生成的配置对象。设置属性ConstantFoldingTimeout达到你想要的价值。

    cfg = coder.config (“自由”);cfg。ConstantFoldingTimeout = 200;
  • 使用应用程序,在项目设置对话框,在所有设置选项卡,设置字段常数合并超时达到你想要的价值。

循环融合

如果可能的话,代码生成器将具有相同运行次数的连续循环融合到生成的代码中的单个循环中。这种优化减少了循环开销。

下面的代码包含连续的循环,它们在代码生成期间被融合。这个函数SumAndProduct求数组中元素的和和积加勒比海盗.该函数使用两个单独的循环来计算和y_f_sum和产品y_f_prod

函数[y_f_sum, y_f_prod] = SumAndProduct (Arr)% # codegeny_f_sum = 0;y_f_prod = 1;i = 1:length(Arr) y_f_sum = y_f_sum+Arr(i);结束i = 1:length(Arr) y_f_prod = y_f_prod*Arr(i);结束

这个MATLAB代码生成的代码在单个循环中计算和和乘积。

逐次矩阵运算组合

如果可能,代码生成器将MATLAB代码中的连续矩阵操作转换为生成代码中的单个循环操作。这种优化减少了在单独的循环中执行矩阵操作所涉及的额外循环开销。

下面的示例包含发生连续矩阵运算的代码。这个函数摆弄矩阵乘以矩阵的每个元素与一个因素.然后,该函数向结果中的每个元素添加一个转变

函数Res =摆弄矩阵(垫,因素,转变)Res =垫*因素;Res = Res +转变;结束

生成的代码将乘法和加法组合成一个循环操作。

遥不可及的代码消除

在可能的情况下,代码生成器抑制对MATLAB代码中不可访问的过程生成代码。例如,如果一个分支elseif,如果别的语句不可达,则不会为该分支生成代码。

下面的示例包含不可访问的代码,在代码生成期间将消除这些代码。这个函数SaturateValue返回一个基于其输入范围的值x

函数y_b = SaturateValue (x)% # codegen如果X >0 y_b = X;elseifx > 10%这是多余的y_b = 10;其他的y_b = - x;结束

第二个分支如果elseif其他的声明是遥不可及的。如果变量x大于10,也大于0。因此,优先执行第一个分支而不是第二个分支。

MATLAB编码器不会为不可达的第二个分支生成代码。

memcpy调用

为了优化复制连续数组元素的生成代码,代码生成器尝试用memcpy调用。一个memcpy调用可以比代码更有效,例如循环或多个连续的元素赋值。

看到memcpy优化

memset调用

为了优化为连续数组元素分配文字常量的生成代码,代码生成器尝试用memset调用。一个memset调用可以比代码更有效,例如循环或多个连续的元素赋值。

看到memset优化