优化生成代码中的隐式扩展
默认情况下,生成代码中的隐式扩展是启用的。代码生成器在生成的代码中引入修改以执行隐式扩展。生成的代码中的更改可能导致额外的代码来扩展操作数。操作数的扩展可能会影响生成代码的性能。请参阅生成启用隐式扩展的代码。
隐式扩展可能会更改支持的运算符和函数的输出大小,从而导致工作流中出现大小和类型不匹配错误。
要精细地控制在生成的代码中何处启用隐式扩展,请在您的 MATLAB® 代码中使用以下函数:
以如下代码片段为例。函数 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 以对该函数的生成代码禁用隐式扩展。
例如,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 执行错误检查,以确保操作数大小相同,并防止代码生成器为该函数生成隐式扩展的代码。
例如,以下代码片段通过使用 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 提供的操作数的大小必须相同。
在工程中禁用隐式扩展
隐式扩展默认启用。如果您不需要在生成的代码中使用隐式扩展,可以禁用启用隐式扩展配置参数。您也可以在代码配置对象中将 EnableImplicitExpansion 属性设置为 false。
通过将模型范围的参数在 MATLAB 函数中启用隐式扩展设置为 false,在 Simulink® 模型中禁用隐式扩展。也可以使用以下命令:
set_param(gcs,'EnableImplicitExpansion',false);注意
在关闭隐式扩展之前,请确保外部代码不使用隐式扩展。如果您的工程包含来自外部源的 MATLAB 代码,则禁用整个工程的隐式扩展可能导致生成代码时出错。
另请参阅
coder.noImplicitExpansionInFunction | coder.sameSizeBinaryOp