Generate Efficient Code Using Unified Analysis
This example shows how to generate efficient code by performing a unified analysis. When you select the configuration parameter Unify buffer reuse candidates, the code generator performs a unified analysis, which first analyzes all potential buffer reuse candidates, identifies the efficient reuses, and then implements them in the generated code. Analyzing the potential buffer reuse candidates and identifying the most efficient reuses upfront reduces missing reuse opportunities, which can significantly reduce RAM consumption and data copies. Buffer reuse candidates refer to buffers that can potentially be reused in the generated code.
Open Example Model
Open the example model IncrementInputs
, which contains the MATLAB Function blocks MFB1
, MFB2
, and MFB3
.
model = 'IncrementInputs';
open_system(model)
The MATLAB Function blocks contain this code to increment the input values by three. The Function packaging parameter of the blocks is set to Nonreusable function
.
function y = fcn(y)
#codegen
y = y+3;
Generate Code Without Unified Analysis
Open the configuration parameters for the model. On the Code Generation > Optimization pane, clear the Unify buffer reuse candidates parameter. Alternatively, use the command-line.
set_param(model,'UnifyBufferReuse','off');
Build the model.
slbuild(model);
### Searching for referenced models in model 'IncrementInputs'. ### Total of 1 models to build. ### Starting build procedure for: IncrementInputs ### Successful completion of build procedure for: IncrementInputs Build Summary Top model targets: Model Build Reason Status Build Duration ================================================================================================================== IncrementInputs Information cache folder or artifacts were missing. Code generated and compiled. 0h 0m 13.663s 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 14.092s
Inspect the generated code in IncrementInputs.c
.
file = fullfile('IncrementInputs_ert_rtw','IncrementInputs.c'); coder.example.extractLines(file,'/* Output and update for atomic system:','/* Model initialize function */',1,1);
/* Output and update for atomic system: '<Root>/MFB1' */ void IncrementInputs_MFB1(void) { IncrementInputs_B.y_l = IncrementInputs_U.Inport; IncrementInputs_B.y_l += 3.0; } /* Output and update for atomic system: '<Root>/MFB2' */ void IncrementInputs_MFB2(void) { IncrementInputs_Y.Out2 = IncrementInputs_B.y_l; IncrementInputs_Y.Out2 += 3.0; } /* Output and update for atomic system: '<Root>/MFB3' */ void IncrementInputs_MFB3(void) { IncrementInputs_Y.Out1 = IncrementInputs_Y.Out2; IncrementInputs_Y.Out1 += 3.0; } /* Model step function */ void IncrementInputs_step(void) { IncrementInputs_MFB1(); IncrementInputs_MFB2(); IncrementInputs_MFB3(); }
The generated code contains the global variable IncrementInputs_B.y_l
to temporarily hold the output of MFB1
and pass the value as the input to MFB2
.
Generate Code with Unified Analysis
Open the configuration parameters for the model. On the Optimization pane, select the Unify buffer reuse candidates parameter. Alternatively, use the command-line.
set_param(model,'UnifyBufferReuse','on');
Build the model.
slbuild(model);
### Searching for referenced models in model 'IncrementInputs'. ### Total of 1 models to build. ### Starting build procedure for: IncrementInputs ### Successful completion of build procedure for: IncrementInputs Build Summary Top model targets: Model Build Reason Status Build Duration ============================================================================================== IncrementInputs Generated code was out of date. Code generated and compiled. 0h 0m 10.91s 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 11.312s
Inspect the generated code in IncrementInputs.c
.
file = fullfile('IncrementInputs_ert_rtw','IncrementInputs.c'); coder.example.extractLines(file,'/* Output and update for atomic system:','/* Model initialize function */',1,1);
/* Output and update for atomic system: '<Root>/MFB1' */ void IncrementInputs_MFB1(void) { IncrementInputs_Y.Out2 = IncrementInputs_U.Inport; IncrementInputs_Y.Out2 += 3.0; } /* Output and update for atomic system: '<Root>/MFB2' */ void IncrementInputs_MFB2(void) { IncrementInputs_Y.Out2 += 3.0; } /* Output and update for atomic system: '<Root>/MFB3' */ void IncrementInputs_MFB3(void) { IncrementInputs_Y.Out1 = IncrementInputs_Y.Out2; IncrementInputs_Y.Out1 += 3.0; } /* Model step function */ void IncrementInputs_step(void) { IncrementInputs_MFB1(); IncrementInputs_MFB2(); IncrementInputs_MFB3(); }
The generated code does not contain the global variable IncrementInputs_B.y_l
to hold the output of MFB1. Instead, the code reuses the root output variable IncrementInputs_Y.Out2
. The Unify buffer reuse candidates optimization instructs the code generator to implement the efficient reuse after analyzing the possible buffer reuse candidates in a unified manner. As a result, the code generator avoids creating the unnecessary global variable and reuses the root outport variable, which reduces RAM consumption and data copies.