Сворачивание выражений оптимизирует код для минимизации вычисления промежуточных результатов на блочных выходах и сохранения таких результатов во временных буферах или переменных. Когда сворачивание выражений включено, генератор кода сворачивает (сворачивает) вычисления блоков в одно выражение вместо создания отдельных инструкций кода и объявлений хранения для каждого блока в модели. Большинство блоков Simulink поддерживают сворачивание выражений.
Сворачивание выражения повышает эффективность генерируемого кода, часто достигая результатов, которые выгодно сравниваются с оптимизированным для рук кодом. Во многих случаях целые группы вычислений модели складываются в единую, высоко оптимизированную линию кода.
model = 'rtwdemo_slexprfold';
open_system(model);

Сворачивание выражений доступно только в том случае, если для параметра Повторное использование хранилища сигналов задано значение on, поскольку сворачивание выражений работает только для выражений, включающих локальные переменные. Параметры Повторное использование хранилища сигналов и Исключить избыточные локальные переменные (сворачивание выражений) включены по умолчанию. Снимите флажок Исключить лишние локальные переменные (сворачивание выражения) или введите следующую команду в окне команд MATLAB, чтобы отключить параметр:
set_param(model, 'ExpressionFolding','off');
Создайте временную папку для процесса сборки и проверки.
currentDir = pwd; [~,cgDir] = rtwdemodir();
Создайте модель.
slbuild(model)
### Starting build procedure for: rtwdemo_slexprfold ### Successful completion of build procedure for: rtwdemo_slexprfold Build Summary Top model targets built: Model Action Rebuild Reason =================================================================================================== rtwdemo_slexprfold Code generated and compiled Code generation information file does not exist. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 6.3738s
При сворачивании выражения в rtwdemo_slexprfold.c перед и в операции блока коммутатора существуют отдельные операторы кода.
cfile = fullfile(cgDir,'rtwdemo_slexprfold_grt_rtw','rtwdemo_slexprfold.c'); rtwdemodbtype(cfile,'/* Model step', '/* Model initialize', 1, 0);
/* Model step function */
void rtwdemo_slexprfold_step(void)
{
real_T rtb_Gain;
boolean_T rtb_LogicalOperator;
boolean_T rtb_RelationalOperator;
/* RelationalOperator: '<Root>/Relational Operator1' incorporates:
* Constant: '<Root>/Constant'
* Inport: '<Root>/In2'
*/
rtb_LogicalOperator = (rtwdemo_slexprfold_P.UPPER >= rtwdemo_slexprfold_U.In2);
/* RelationalOperator: '<Root>/Relational Operator' incorporates:
* Constant: '<Root>/Constant1'
* Inport: '<Root>/In2'
*/
rtb_RelationalOperator = (rtwdemo_slexprfold_U.In2 <=
rtwdemo_slexprfold_P.LOWER);
/* Logic: '<Root>/Logical Operator' */
rtb_LogicalOperator = (rtb_LogicalOperator || rtb_RelationalOperator);
/* Switch: '<Root>/Switch' */
if (rtb_LogicalOperator) {
/* Gain: '<Root>/Gain' incorporates:
* Inport: '<Root>/In1'
*/
rtb_Gain = 2.0 * rtwdemo_slexprfold_U.In1;
/* Lookup_n-D: '<Root>/Look-Up Table' incorporates:
* Gain: '<Root>/Gain'
*/
rtwdemo_slexprfold_Y.Out1 = look1_binlx(rtb_Gain,
rtwdemo_slexprfold_P.T1Break, rtwdemo_slexprfold_P.T1Data, 10U);
} else {
/* Lookup_n-D: '<Root>/Look-Up Table' incorporates:
* Inport: '<Root>/In3'
* Inport: '<Root>/In4'
* Lookup_n-D: '<Root>/Look-Up Table (2-D)'
*/
rtwdemo_slexprfold_Y.Out1 = look2_binlx(rtwdemo_slexprfold_U.In3,
rtwdemo_slexprfold_U.In4, rtwdemo_slexprfold_P.T2Break,
rtwdemo_slexprfold_P.T2Break, rtwdemo_slexprfold_P.T2Data,
rtCP_LookUpTable2D_maxIndex, 3U);
}
/* End of Switch: '<Root>/Switch' */
}
Введите следующую команду для включения сворачивания выражения:
set_param(model, 'ExpressionFolding','on');
Создайте модель.
slbuild(model);
### Starting build procedure for: rtwdemo_slexprfold ### Successful completion of build procedure for: rtwdemo_slexprfold Build Summary Top model targets built: Model Action Rebuild Reason ================================================================================== rtwdemo_slexprfold Code generated and compiled Generated code was out of date. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 5.4258s
Ниже приводится часть rtwdemo_slexprfold.c. В оптимизированном коде генератор кода сворачивает все вычисления в операцию Switch block.
rtwdemodbtype(cfile,'/* Model step', '/* Model initialize', 1, 0);
/* Model step function */
void rtwdemo_slexprfold_step(void)
{
/* Switch: '<Root>/Switch' incorporates:
* Constant: '<Root>/Constant'
* Constant: '<Root>/Constant1'
* Inport: '<Root>/In2'
* Logic: '<Root>/Logical Operator'
* RelationalOperator: '<Root>/Relational Operator'
* RelationalOperator: '<Root>/Relational Operator1'
*/
if ((rtwdemo_slexprfold_P.UPPER >= rtwdemo_slexprfold_U.In2) ||
(rtwdemo_slexprfold_U.In2 <= rtwdemo_slexprfold_P.LOWER)) {
/* Outport: '<Root>/Out1' incorporates:
* Gain: '<Root>/Gain'
* Inport: '<Root>/In1'
* Lookup_n-D: '<Root>/Look-Up Table'
*/
rtwdemo_slexprfold_Y.Out1 = look1_binlx(2.0 * rtwdemo_slexprfold_U.In1,
rtwdemo_slexprfold_P.T1Break, rtwdemo_slexprfold_P.T1Data, 10U);
} else {
/* Outport: '<Root>/Out1' incorporates:
* Inport: '<Root>/In3'
* Inport: '<Root>/In4'
* Lookup_n-D: '<Root>/Look-Up Table (2-D)'
*/
rtwdemo_slexprfold_Y.Out1 = look2_binlx(rtwdemo_slexprfold_U.In3,
rtwdemo_slexprfold_U.In4, rtwdemo_slexprfold_P.T2Break,
rtwdemo_slexprfold_P.T2Break, rtwdemo_slexprfold_P.T2Data,
rtCP_LookUpTable2D_maxIndex, 3U);
}
/* End of Switch: '<Root>/Switch' */
}
Закройте отчет о модели и создании кода.
bdclose(model) rtwdemoclean; cd(currentDir)
Для примера, в котором выражения кода складываются между Simulink и Stateflow, откройте эту модель. rtwdemo_sfexprfold.