优化生成代码中的隐式扩展
默认情况下,生成代码中的隐式扩展是启用的。代码生成器在生成的代码中引入修改以执行隐式扩展。生成的代码中的更改可能导致额外的代码来扩展操作数。操作数的扩展可能会影响生成代码的性能。请参阅生成启用隐式扩展的代码 (MATLAB Coder)。
隐式扩展可能会更改支持的运算符和函数的输出大小,从而导致工作流中出现大小和类型不匹配错误。
要精细地控制在生成的代码中何处启用隐式扩展,请在您的 MATLAB® 代码中使用以下函数:
coder.noImplicitExpansionInFunction
(MATLAB Coder)coder.sameSizeBinaryOp
(MATLAB Coder)
以如下代码片段为例。函数 vector_sum
求两个大小兼容的数组之和。
function out = vector_sum(a,b) out = b + a; end
操作数 a 和 b 的类型定义如下:
a_type = coder.typeof(1,[2 1]) %size: 2x1 b_type = coder.typeof(1,[2 Inf]) %size: 2x:inf
如果没有隐式扩展,out
变量的大小计算为 2x1
。
如果使用隐式扩展,变量 out
的大小计算为 2x:?
。
这些代码片段概要显示在函数 vector_sum
的生成代码中的变化,分别包含禁用和启用隐式扩展的情况。为了生成代码,操作数 a
和 b
的类型定义为:
a_type = coder.typeof(1,[1 Inf]) %size: 1x:inf b_type = coder.typeof(1,[1 Inf]) %size: 1x:inf
禁用隐式扩展时生成的代码 | 启用隐式扩展时生成的代码 |
---|---|
void vector_sum(const emxArray_real_T *a, const emxArray_real_T *b, emxArray_real_T *out) { int i; int loop_ub; i = out->size[0] * out->size[1]; out->size[0] = 1; out->size[1] = b->size[1]; emxEnsureCapacity_real_T(out, i); loop_ub = b->size[1]; for (i = 0; i < loop_ub; i++) { out->data[i] = b->data[i] + a->data[i]; } } | static void plus(emxArray_real_T *out, const emxArray_real_T *b, const emxArray_real_T *a) { int i; .... if (a->size[1] == 1) { out->size[1] = b->size[1]; } else { out->size[1] = a->size[1]; } .... if (a->size[1] == 1) { loop_ub = b->size[1]; } else { loop_ub = a->size[1]; } for (i = 0; i < loop_ub; i++) { out->data[i] = b->data[i * stride_0_1] + a->data[i * stride_1_1]; } } void vector_sum(const emxArray_real_T *a, const emxArray_real_T *b, emxArray_real_T *out) { int i; int loop_ub; if (b->size[1] == a->size[1]) { i = out->size[0] * out->size[1]; out->size[0] = 1; out->size[1] = b->size[1]; emxEnsureCapacity_real_T(out, i); loop_ub = b->size[1]; for (i = 0; i < loop_ub; i++) { out->data[i] = b->data[i] + a->data[i]; } } else { plus(out, b, a); } } |
使用 coder.noImplicitExpansionInFunction
在指定函数中禁用隐式扩展
如果您需要在工程中进行隐式扩展,但不需要在特定函数中进行隐式扩展,请通过在该函数中调用 coder.noImplicitExpansionInFunction
(MATLAB Coder) 以对该函数的生成代码禁用隐式扩展。
例如,vector_sum
的生成代码不应用隐式扩展。
MATLAB 代码 | 使用 coder.sameSizeBinaryOp 生成的代码 |
---|---|
function out = vector_sum(a,b) coder.noImplicitExpansionInFunction(); out = a + b; end a = coder.typeof(1,[1 Inf]) %size: 1x:inf b = coder.typeof(1,[1 Inf]) %size: 1x:inf codegen vector_sum -launchreport ... -args {a,b} -config:lib | void vector_sum(const emxArray_real_T *a, const emxArray_real_T *b, emxArray_real_T *out) { int i; int loop_ub; i = out->size[0] * out->size[1]; out->size[0] = 1; out->size[1] = a->size[1]; emxEnsureCapacity_real_T(out, i); loop_ub = a->size[1]; for (i = 0; i < loop_ub; i++) { out->data[i] = a->data[i] + b->data[i]; } } |
注意
coder.noImplicitExpansionInFunction
不在 MATLAB 代码中禁用隐式扩展。它仅在生成的代码中禁用隐式扩展。
使用 coder.sameSizeBinaryOp
禁用特定二元运算的隐式扩展
使用函数 coder.sameSizeBinaryOp
(MATLAB Coder) 执行错误检查,以确保操作数大小相同,并防止代码生成器为该函数生成隐式扩展的代码。
例如,以下代码片段通过使用 coder.sameSizeBinaryOp
应用加法运算,而没有隐式扩展。
MATLAB 代码 | 生成的代码 |
---|---|
function out = vector_sum(a,b) out = coder.sameSizeBinaryOp(@plus, a, b); end a = coder.typeof(1,[1 Inf]) %size: 1x:inf b = coder.typeof(1,[1 Inf]) %size: 1x:inf codegen vector_sum -launchreport ... -args {a,b} -config:lib | void vector_sum(const emxArray_real_T *a, const emxArray_real_T *b, emxArray_real_T *out) { int i; int loop_ub; i = out->size[0] * out->size[1]; out->size[0] = 1; out->size[1] = a->size[1]; emxEnsureCapacity_real_T(out, i); loop_ub = a->size[1]; for (i = 0; i < loop_ub; i++) { out->data[i] = a->data[i] + b->data[i]; } } |
coder.sameSizeBinaryOp
不支持标量扩展。为 coder.sameSizeBinaryOp
提供的操作数的大小必须相同。
在工程中禁用隐式扩展
隐式扩展默认启用。如果您不需要在生成的代码中使用隐式扩展,可以禁用启用隐式扩展 (MATLAB Coder)配置参数。您也可以在代码配置对象中将 EnableImplicitExpansion
属性设置为 false
。
通过将模型范围的参数在 MATLAB 函数中启用隐式扩展设置为 false
,在 Simulink® 模型中禁用隐式扩展。也可以使用以下命令:
set_param(gcs,'EnableImplicitExpansion',false);
注意
在关闭隐式扩展之前,请确保外部代码不使用隐式扩展。如果您的工程包含来自外部源的 MATLAB 代码,则禁用整个工程的隐式扩展可能导致生成代码时出错。
另请参阅
coder.noImplicitExpansionInFunction
(MATLAB Coder) | coder.sameSizeBinaryOp
(MATLAB Coder)
主题
- 生成启用隐式扩展的代码 (MATLAB Coder)
- 基本运算的兼容数组大小
- 解决错误:左侧是固定大小,而右侧是可变大小 (MATLAB Coder)