Сворачивание выражения оптимизирует код, чтобы минимизировать расчет промежуточных результатов в блоке выходные параметры и устройство хранения данных таких результатов во временных буферах или переменных. Когда сворачивание выражения включено, коллапсы генератора кода (сгибы) блокируют расчеты в отдельное выражение, вместо того, чтобы генерировать отдельные операторы кода и объявления устройства хранения данных для каждого блока в модели. Большинство блоков Simulink поддерживает сворачивание выражения.
Сворачивание выражения повышает эффективность сгенерированного кода, часто достигая результатов, которые выдерживают сравнение с ручным оптимизированным кодом. Во многих случаях целые группы расчетов модели сворачиваются в одну, высоко оптимизированную строку кода.
model = 'rtwdemo_slexprfold';
open_system(model);
Сворачивание выражения доступно только, когда параметр Повторного использования памяти устанавливается на на том, потому что сворачивание выражения работает только с выражениями, включающими локальные переменные. Повторное использование памяти и Устраняет лишние локальные переменные (сворачивание выражения), параметры включены по умолчанию. Очистите Устранение лишних локальных переменных (сворачивание выражения) параметр или введите следующую команду в командное окно MATLAB, чтобы выключить параметр:
set_param(model, 'ExpressionFolding','off');
Создайте временную папку для сборки и инспекционного процесса.
currentDir = pwd; [~,cgDir] = rtwdemodir();
Создайте модель.
rtwbuild(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.7663s
С выражением, сворачивающимся прочь, в rtwdemo_slexprfold.c
файл, существуют отдельные операторы кода прежде и в операции блока switch.
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');
Создайте модель.
rtwbuild(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.5165s
Следующее является фрагментом rtwdemo_slexprfold.c. В оптимизированном коде генератор кода сворачивает все расчеты в операцию блока switch.
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
.