Генератор кода оптимизирует сгенерированный код для назначений векторного сигнала, пытаясь заменить for
циклически управляемые назначения элементов и memcpy
вызовы функций с назначениями указателей. Назначения указателей позволяют избежать дорогостоящих копий данных. Поэтому они используют меньше пространства в стеке и предлагают более высокую скорость выполнения, чем for
циклически управляемые назначения элементов и memcpy
вызовы функций. Если вы присвоите большие наборы данных векторным сигналам, эта оптимизация может привести к значительному улучшению эффективности кода.
Чтобы применить эту оптимизацию:
Проверьте, что ваш целевой объект поддерживает memcpy
функция.
Определите, использует ли ваша модель назначения векторных сигналов (таких как Y=expression
) перемещать большие объемы данных. Для примера ваша модель может использовать блок Selector, чтобы выбрать элементы входа из вектора, матрицы или мультиразмерность сигнала.
На панели Оптимизации параметр Use memcpy for vector assignment, который включен по умолчанию, включает связанный параметр Memcpy threshold (bytes).
Исследуйте настройку порога Memcpy (байт). По умолчанию он задает 64 байта как минимальный размер массива, для которого memcpy
вызовы функций или назначения указателей могут заменить for
циклы в сгенерированном коде. Основываясь на размерах массивов в назначениях векторного сигнала вашего приложения и факторах целевого окружения при выборе порога, примите значение по умолчанию или задайте другой размер массива.
Рассмотрим следующую модель с именем rtwdemo_pointer_conversion. Эта модель использует блок Switch, чтобы назначить данные сигналу векторы. Этот сигнал затем подается в блок Bus Selector.
В диалоговом окне Параметров конфигурации снимите флажок Использовать memcpy для вектора назначения.
Создайте временную папку для процесса сборки и проверки.
Нажмите Ctrl + B, чтобы сгенерировать код.
### Starting build procedure for: rtwdemo_pointer_conversion ### Successful completion of build procedure for: rtwdemo_pointer_conversion Build Summary Top model targets built: Model Action Rebuild Reason =========================================================================================================== rtwdemo_pointer_conversion 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.179s
Просмотрите сгенерированный код без оптимизации. Вот фрагмент rtwdemo_pointer_conversion.c
.
/* Model step function */ void rtwdemo_pointer_conversion_step(void) { int32_T i; int16_T rtb_dataX[100]; int16_T rtb_dataY[100]; /* Switch generated from: '<Root>/Switch' incorporates: * Constant: '<Root>/Constant' * Constant: '<Root>/Constant1' * Constant: '<Root>/Constant2' * Constant: '<Root>/Constant3' * Inport: '<Root>/In1' */ for (i = 0; i < 100; i++) { if (rtU.In1) { rtb_dataX[i] = rtCP_Constant_Value[i]; rtb_dataY[i] = rtCP_Constant1_Value[i]; } else { rtb_dataX[i] = rtCP_Constant2_Value[i]; rtb_dataY[i] = rtCP_Constant3_Value[i]; } } /* End of Switch generated from: '<Root>/Switch' */ /* S-Function (sfix_look1_dyn): '<Root>/Lookup Table Dynamic' incorporates: * Inport: '<Root>/In2' * Outport: '<Root>/Out1' */ /* Dynamic Look-Up Table Block: '<Root>/Lookup Table Dynamic' * Input0 Data Type: Integer S16 * Input1 Data Type: Integer S16 * Input2 Data Type: Integer S16 * Output0 Data Type: Integer S16 * Lookup Method: Linear_Endpoint * */ LookUp_S16_S16( &(rtY.Out1), &rtb_dataY[0], rtU.In2, &rtb_dataX[0], 99U); }
Без оптимизации сгенерированный код содержит for
циклически управляемые назначения элементов.
В диалоговом окне Параметра конфигурации выберите параметр Use memcpy for вектора assignment.
Сгенерируйте код.
### Starting build procedure for: rtwdemo_pointer_conversion ### Successful completion of build procedure for: rtwdemo_pointer_conversion Build Summary Top model targets built: Model Action Rebuild Reason ========================================================================================== rtwdemo_pointer_conversion 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.7114s
Просмотрите сгенерированный код без оптимизации. Вот фрагмент rtwdemo_pointer_conversion.c
.
/* Model step function */ void rtwdemo_pointer_conversion_step(void) { const int16_T *rtb_dataX_0; const int16_T *rtb_dataY_0; /* Inport: '<Root>/In1' */ if (rtU.In1) { /* Switch generated from: '<Root>/Switch' incorporates: * Constant: '<Root>/Constant' */ rtb_dataX_0 = &rtCP_Constant_Value[0]; /* Switch generated from: '<Root>/Switch' incorporates: * Constant: '<Root>/Constant1' */ rtb_dataY_0 = &rtCP_Constant1_Value[0]; } else { /* Switch generated from: '<Root>/Switch' incorporates: * Constant: '<Root>/Constant2' */ rtb_dataX_0 = &rtCP_Constant2_Value[0]; /* Switch generated from: '<Root>/Switch' incorporates: * Constant: '<Root>/Constant3' */ rtb_dataY_0 = &rtCP_Constant3_Value[0]; } /* End of Inport: '<Root>/In1' */ /* S-Function (sfix_look1_dyn): '<Root>/Lookup Table Dynamic' incorporates: * Inport: '<Root>/In2' * Outport: '<Root>/Out1' */ /* Dynamic Look-Up Table Block: '<Root>/Lookup Table Dynamic' * Input0 Data Type: Integer S16 * Input1 Data Type: Integer S16 * Input2 Data Type: Integer S16 * Output0 Data Type: Integer S16 * Lookup Method: Linear_Endpoint * */ LookUp_S16_S16( &(rtY.Out1), &rtb_dataY_0[0], rtU.In2, &rtb_dataX_0[0], 99U); }
Поскольку установка параметра Memcpy threshold (bytes) ниже размеров массива в сгенерированном коде, оптимизированный код содержит назначения указателей для назначений векторного сигнала.
Порог Memcpy (байт) | Используйте memcpy для назначения векторов