Для повышения эффективности выполнения генератор кода может изменять порядок выполнения блока. В диалоговом окне «Параметры конфигурации» при установке для параметра «Оптимизировать порядок блоков» значения Improved Execution Speed, генератор кода может изменить порядок работы блока для реализации этих оптимизаций:
Исключение копий данных для блоков, выполняющих операции inplace (т. е. использующих одну и ту же входную и выходную переменную) и содержащих код алгоритма с ненужными копиями данных.
Объединить больше for выполняет циклы путем совместного выполнения блоков одинакового размера.
Повторно используйте ту же переменную для ввода, вывода и состояния блока единичной задержки, выполнив блок единичной задержки перед блоками восходящего направления.
Эти оптимизации повышают скорость выполнения и экономят ОЗУ и ПЗУ.
Откройте matlab:rtwdemo_optimizeblockorder модели. Эта модель содержит три подсистемы для демонстрации повышения эффективности выполнения операций переупорядочивания блоков.

for Слияние петельПодсистема LoopFusionScheduling показывает, как генератор кода переупорядочивает операции блока так, что блоки, имеющие одинаковый выходной размер, выполняются вместе. Это изменение порядка активирует for слияние петель. Установите для параметра «Оптимизировать порядок блоков» значение Off.
Во временной папке системы создайте папку для процесса сборки и проверки и создайте модель.
### Starting build procedure for: rtwdemo_optimizeblockorder ### Successful completion of build procedure for: rtwdemo_optimizeblockorder Build Summary Top model targets built: Model Action Rebuild Reason =========================================================================================================== rtwdemo_optimizeblockorder 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 12.873s
Просмотр созданного кода без оптимизации. Код для LoopFusionScheduling подсистема:
/* Output and update for atomic system: '<Root>/LoopFusionScheduling' */
static void LoopFusionScheduling(const real_T rtu_In1[6], const real_T rtu_In2[6],
const real_T rtu_In3[6], const real_T rtu_In4[6], real_T rty_Out1[6], real_T
rty_Out2[9], real_T rty_Out3[6], real_T rty_Out4[9])
{
int32_T i;
int32_T i_0;
int32_T tmp;
int32_T tmp_0;
/* Bias: '<S2>/Bias' incorporates:
* Gain: '<S2>/Gain'
*/
for (i = 0; i < 6; i++) {
rty_Out1[i] = -0.3 * rtu_In1[i] + 0.5;
}
/* End of Bias: '<S2>/Bias' */
/* Product: '<S2>/Product' */
for (i = 0; i < 3; i++) {
for (i_0 = 0; i_0 < 3; i_0++) {
tmp = i_0 + 3 * i;
rty_Out2[tmp] = 0.0;
tmp_0 = i << 1;
rty_Out2[tmp] += rtu_In2[tmp_0] * rtu_In1[i_0];
rty_Out2[tmp] += rtu_In2[tmp_0 + 1] * rtu_In1[i_0 + 3];
}
}
/* End of Product: '<S2>/Product' */
/* Bias: '<S2>/Bias1' incorporates:
* Gain: '<S2>/Gain1'
*/
for (i = 0; i < 6; i++) {
rty_Out3[i] = -0.3 * rtu_In3[i] + 0.5;
}
/* End of Bias: '<S2>/Bias1' */
/* Product: '<S2>/Product1' */
for (i = 0; i < 3; i++) {
for (i_0 = 0; i_0 < 3; i_0++) {
tmp = i_0 + 3 * i;
rty_Out4[tmp] = 0.0;
tmp_0 = i << 1;
rty_Out4[tmp] += rtu_In4[tmp_0] * rtu_In3[i_0];
rty_Out4[tmp] += rtu_In4[tmp_0 + 1] * rtu_In3[i_0 + 3];
}
}
/* End of Product: '<S2>/Product1' */
}
С порядком выполнения по умолчанию блоки выполняются слева направо и сверху вниз. В результате есть отдельные for контуры для двух комбинаций блоков усиления и смещения и блоков изделия.
Создайте код с оптимизацией. Установите для параметра «Оптимизировать порядок блоков» значение Improved Execution Speed и построить модель.
### Starting build procedure for: rtwdemo_optimizeblockorder ### Successful completion of build procedure for: rtwdemo_optimizeblockorder Build Summary Top model targets built: Model Action Rebuild Reason ========================================================================================== rtwdemo_optimizeblockorder 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 9.8141s
Просмотр созданного кода с оптимизацией.
/* Output and update for atomic system: '<Root>/LoopFusionScheduling' */
static void LoopFusionScheduling(const real_T rtu_In1[6], const real_T rtu_In2[6],
const real_T rtu_In3[6], const real_T rtu_In4[6], real_T rty_Out1[6], real_T
rty_Out2[9], real_T rty_Out3[6], real_T rty_Out4[9])
{
int32_T i;
int32_T i_0;
int32_T tmp;
int32_T tmp_0;
for (i = 0; i < 3; i++) {
for (i_0 = 0; i_0 < 3; i_0++) {
/* Product: '<S2>/Product' incorporates:
* Product: '<S2>/Product1'
*/
tmp = i_0 + 3 * i;
rty_Out2[tmp] = 0.0;
/* Product: '<S2>/Product1' */
rty_Out4[tmp] = 0.0;
/* Product: '<S2>/Product' incorporates:
* Product: '<S2>/Product1'
*/
tmp_0 = i << 1;
rty_Out2[tmp] += rtu_In2[tmp_0] * rtu_In1[i_0];
/* Product: '<S2>/Product1' */
rty_Out4[tmp] += rtu_In4[tmp_0] * rtu_In3[i_0];
/* Product: '<S2>/Product' */
rty_Out2[tmp] += rtu_In2[tmp_0 + 1] * rtu_In1[i_0 + 3];
/* Product: '<S2>/Product1' incorporates:
* Product: '<S2>/Product'
*/
rty_Out4[tmp] += rtu_In4[tmp_0 + 1] * rtu_In3[i_0 + 3];
}
}
for (i = 0; i < 6; i++) {
/* Bias: '<S2>/Bias' incorporates:
* Gain: '<S2>/Gain'
*/
rty_Out1[i] = -0.3 * rtu_In1[i] + 0.5;
/* Bias: '<S2>/Bias1' incorporates:
* Gain: '<S2>/Gain1'
*/
rty_Out3[i] = -0.3 * rtu_In3[i] + 0.5;
}
}
В оптимизированном коде блоки с одинаковым размером вывода выполняются вместе. Два набора блоков усиления и смещения имеют размер выходного размера, равный 6, так что они исполняют вместе. Блоки продукта имеют размер выходного размера 9, так что они исполняют вместе. Слияние for циклы позволяют генератору кода устанавливать значение выражения 3 * i + i_0 равно временной переменной tmp_0. Эта оптимизация также повышает эффективность выполнения.
Подсистема RegionScheduling На показано, как генератор кода переупорядочивает операции блока, чтобы разрешить повторное использование буфера для ввода, вывода и состояния блоков единичной задержки. Когда вычисление является частью отдельных областей, которые соединяются только через блоки задержки, генератор кода может изменить порядок выполнения блока так, чтобы дочерние области выполнялись перед вышестоящими областями. Этот порядок выполнения обеспечивает максимальное повторное использование состояний блока задержки и входных и выходных переменных. Установите для параметра «Оптимизировать порядок блоков» значение Off и построить модель.
### Starting build procedure for: rtwdemo_optimizeblockorder ### Successful completion of build procedure for: rtwdemo_optimizeblockorder Build Summary Top model targets built: Model Action Rebuild Reason ========================================================================================== rtwdemo_optimizeblockorder 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 9.6046s
Просмотр созданного кода без оптимизации. Код для RegionScheduling подсистема:
/* Output and update for atomic system: '<Root>/RegionScheduling' */
static void RegionScheduling(const real_T rtu_In1[6], const real_T rtu_In2[6],
real_T rty_Out1[6], rtDW_RegionScheduling *localDW)
{
real_T rtb_Sum;
int32_T i;
for (i = 0; i < 6; i++) {
/* Sum: '<S3>/Sum' incorporates:
* UnitDelay: '<S3>/Delay'
* UnitDelay: '<S3>/UnitDelay'
*/
rtb_Sum = localDW->Delay_DSTATE[i] + localDW->UnitDelay_DSTATE[i];
/* UnitDelay: '<S3>/UnitDelay2' */
rty_Out1[i] = localDW->UnitDelay2_DSTATE[i];
/* Update for UnitDelay: '<S3>/Delay' incorporates:
* Bias: '<S3>/Bias'
*/
localDW->Delay_DSTATE[i] = rtu_In1[i] + 3.0;
/* Update for UnitDelay: '<S3>/UnitDelay' incorporates:
* Gain: '<S3>/Gain'
*/
localDW->UnitDelay_DSTATE[i] = 2.0 * rtu_In2[i];
/* Update for UnitDelay: '<S3>/UnitDelay2' */
localDW->UnitDelay2_DSTATE[i] = rtb_Sum;
}
}
В порядке выполнения по умолчанию созданный код содержит дополнительную временную переменную. rtb_Sum и копия данных.
Создайте код с оптимизацией. Установите для параметра «Оптимизировать порядок блоков» значение Improved Execution Speed и построить модель.
### Starting build procedure for: rtwdemo_optimizeblockorder ### Successful completion of build procedure for: rtwdemo_optimizeblockorder Build Summary Top model targets built: Model Action Rebuild Reason ========================================================================================== rtwdemo_optimizeblockorder 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 9.8528s
Просмотр созданного кода с оптимизацией.
/* Output and update for atomic system: '<Root>/RegionScheduling' */
static void RegionScheduling(const real_T rtu_In1[6], const real_T rtu_In2[6],
real_T rty_Out1[6], rtDW_RegionScheduling *localDW)
{
int32_T i;
for (i = 0; i < 6; i++) {
/* UnitDelay: '<S3>/UnitDelay2' */
rty_Out1[i] = localDW->UnitDelay2_DSTATE[i];
/* Sum: '<S3>/Sum' incorporates:
* UnitDelay: '<S3>/Delay'
* UnitDelay: '<S3>/UnitDelay'
* UnitDelay: '<S3>/UnitDelay2'
*/
localDW->UnitDelay2_DSTATE[i] = localDW->Delay_DSTATE[i] +
localDW->UnitDelay_DSTATE[i];
/* Bias: '<S3>/Bias' incorporates:
* UnitDelay: '<S3>/Delay'
*/
localDW->Delay_DSTATE[i] = rtu_In1[i] + 3.0;
/* Gain: '<S3>/Gain' incorporates:
* UnitDelay: '<S3>/UnitDelay'
*/
localDW->UnitDelay_DSTATE[i] = 2.0 * rtu_In2[i];
}
}
В оптимизированном коде блоки в областях 3, 2 и 1 выполняются в таком порядке. При таком порядке выполнения созданный код не содержит временную переменную. rtb_Sum и соответствующую копию данных.
Подсистема InplaceScheduling показывает, как генератор кода переупорядочивает операции блока для исключения копий данных для блоков, выполняющих операции inplace. В диалоговом окне «Параметры конфигурации» задайте для параметра «Оптимизировать порядок блоков» значение Off и построить модель.
### Starting build procedure for: rtwdemo_optimizeblockorder ### Successful completion of build procedure for: rtwdemo_optimizeblockorder Build Summary Top model targets built: Model Action Rebuild Reason ========================================================================================== rtwdemo_optimizeblockorder 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 9.2423s
Просмотр созданного кода без оптимизации. Код для InplaceScheduling подсистема:
/* Output and update for atomic system: '<Root>/InplaceScheduling' */
static void InplaceScheduling(void)
{
real_T rtb_Max[6];
real_T acc;
int32_T idx1;
int32_T idx2;
int32_T k;
for (idx1 = 0; idx1 < 6; idx1++) {
/* Sum: '<S1>/Sum2x3' incorporates:
* Inport: '<Root>/In7'
* UnitDelay: '<S1>/Unit Delay'
*/
rtDWork.UnitDelay_DSTATE[idx1] += rtU.In7[idx1];
/* MinMax: '<S1>/Max' */
acc = rtDWork.UnitDelay_DSTATE[idx1];
if (2.0 > acc) {
rtb_Max[idx1] = 2.0;
} else {
rtb_Max[idx1] = acc;
}
/* End of MinMax: '<S1>/Max' */
}
/* S-Function (sdsp2norm2): '<S1>/Normalization' incorporates:
* Outport: '<Root>/Out7'
*/
idx1 = 0;
idx2 = 0;
acc = 0.0;
for (k = 0; k < 6; k++) {
acc += rtb_Max[idx1] * rtb_Max[idx1];
idx1++;
}
acc = 1.0 / (sqrt(acc) + 1.0E-10);
for (k = 0; k < 6; k++) {
rtY.Out7[idx2] = rtb_Max[idx2] * acc;
idx2++;
/* Outport: '<Root>/Out6' incorporates:
* Bias: '<S1>/Bias'
* Inport: '<Root>/In8'
* Outport: '<Root>/Out7'
* Product: '<S1>/Product'
*/
rtY.Out6[k] = (rtU.In8 + 1.0) * rtDWork.UnitDelay_DSTATE[k];
/* Switch: '<S1>/Switch' incorporates:
* Inport: '<Root>/In9'
*/
if (rtU.In9[k] > 0.0) {
/* Update for UnitDelay: '<S1>/Unit Delay' */
rtDWork.UnitDelay_DSTATE[k] = 0.0;
} else {
/* Update for UnitDelay: '<S1>/Unit Delay' */
rtDWork.UnitDelay_DSTATE[k] = rtb_Max[k];
}
/* End of Switch: '<S1>/Switch' */
}
/* End of S-Function (sdsp2norm2): '<S1>/Normalization' */
}
С порядком выполнения по умолчанию блок Max выполняется перед блоком Product. Для сохранения вывода блока Sum созданный код содержит две переменные: UnitDelay_DSTATE и rtb_Max.
Создайте код с оптимизацией. Установите для параметра «Оптимизировать порядок блоков» значение Improved Execution Speed и построить модель.
### Starting build procedure for: rtwdemo_optimizeblockorder ### Successful completion of build procedure for: rtwdemo_optimizeblockorder Build Summary Top model targets built: Model Action Rebuild Reason ========================================================================================== rtwdemo_optimizeblockorder 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 9.9044s
Просмотр созданного кода с оптимизацией.
/* Output and update for atomic system: '<Root>/InplaceScheduling' */
static void InplaceScheduling(void)
{
real_T acc;
int32_T idx1;
int32_T idx2;
int32_T k;
for (idx1 = 0; idx1 < 6; idx1++) {
/* Sum: '<S1>/Sum2x3' incorporates:
* Inport: '<Root>/In7'
* UnitDelay: '<S1>/Unit Delay'
*/
rtDWork.UnitDelay_DSTATE[idx1] += rtU.In7[idx1];
/* Outport: '<Root>/Out6' incorporates:
* Bias: '<S1>/Bias'
* Inport: '<Root>/In8'
* Product: '<S1>/Product'
*/
rtY.Out6[idx1] = (rtU.In8 + 1.0) * rtDWork.UnitDelay_DSTATE[idx1];
/* MinMax: '<S1>/Max' */
acc = rtDWork.UnitDelay_DSTATE[idx1];
if (2.0 > acc) {
rtDWork.UnitDelay_DSTATE[idx1] = 2.0;
} else {
rtDWork.UnitDelay_DSTATE[idx1] = acc;
}
/* End of MinMax: '<S1>/Max' */
}
/* S-Function (sdsp2norm2): '<S1>/Normalization' incorporates:
* Outport: '<Root>/Out7'
*/
idx1 = 0;
idx2 = 0;
acc = 0.0;
for (k = 0; k < 6; k++) {
acc += rtDWork.UnitDelay_DSTATE[idx1] * rtDWork.UnitDelay_DSTATE[idx1];
idx1++;
}
acc = 1.0 / (sqrt(acc) + 1.0E-10);
for (k = 0; k < 6; k++) {
rtY.Out7[idx2] = rtDWork.UnitDelay_DSTATE[idx2] * acc;
idx2++;
}
/* End of S-Function (sdsp2norm2): '<S1>/Normalization' */
/* Update for UnitDelay: '<S1>/Unit Delay' */
for (idx1 = 0; idx1 < 6; idx1++) {
/* Switch: '<S1>/Switch' incorporates:
* Inport: '<Root>/In9'
*/
if (rtU.In9[idx1] > 0.0) {
rtDWork.UnitDelay_DSTATE[idx1] = 0.0;
}
/* End of Switch: '<S1>/Switch' */
}
/* End of Update for UnitDelay: '<S1>/Unit Delay' */
}
Оптимизированный код не содержит переменную rtb_Max или копии данных. Созданный код содержит одну переменную, UnitDelay_DSTATE, для удержания вывода блока Sum. Блок продукта считывает из UnitDelay_DSTATE и блок Max считывает из и записывает в UnitDelay_DSTATE.
Для реализации повторного использования буфера генератор кода не нарушает заданные пользователем приоритеты блоков.
Оптимизация порядка работы блока в сгенерированном коде