Если модель имеет оптимальные параметры для удаления копий данных, можно удалить дополнительные копии данных с помощью Simulink.Signal объекты для указания повторного использования буфера. Изучив сгенерированный код и Отчет о показателях статического кода и определив области, в которых, по вашему мнению, возможно повторное использование буфера, можно указать сигнальные объекты на сигнальных линиях.
Можно указать повторное использование буфера для сигналов, включающих пару корневых сигналов ввода и вывода. Можно также указать повторное использование буфера только для пары корневых входных и выходных сигналов. Эта оптимизация уменьшает потребление ПЗУ и ОЗУ, поскольку в сгенерированном коде меньше глобальных переменных и копий данных. Скорость выполнения кода также увеличивается.
Модель rtwdemo_reusable_csc содержащая неиспользуемую подсистему DeltaSubsystem и функциональный блок MATLAB Downsample. DeltaSubsystem содержит функциональные блоки MATLAB DeltaX и DeltaY.
model ='rtwdemo_reusable_csc';
open_system(model);

В коллекции Приложения в разделе Создание кода щелкните Встроенный кодер. Откроется вкладка Код C (C Code).
Чтобы открыть редактор сопоставлений кода, щелкните Интерфейс кода > Сопоставления кодов отдельных элементов.
В модели выберите RCSC_REAL сигнальная линия. Для просмотра этого сигнала или любого сигнала в редакторе сопоставлений кодов на вкладке Signals/States нажмите кнопку Add selected signals to code mappings.
Для строки, представляющей сигнальную линию, проверьте столбец Storage Class. Сигнальный объект использует класс хранения Reusable, что означает, что объект отображается в сгенерированном коде как глобальная переменная с именем RCSC_REAL.
В модели перейдите в папку DeltaSubsystem подсистема.
Выберите RCSC_REAL сигнальная линия в этой подсистеме. Этот сигнал также преобразуется в объект сигнала в базовой рабочей области.
С помощью Reusable класс хранения, сгенерированный код может хранить выходные данные Complex to Real-Imag блок (на корневом уровне модели) и выходные данные DeltaX блок (в подсистеме) в RCSC_REAL глобальная переменная.
Создайте модель.
currentDir = pwd; [~,cgDir] = rtwdemodir(); slbuild(model);
### Starting build procedure for: rtwdemo_reusable_csc ### Successful completion of build procedure for: rtwdemo_reusable_csc Build Summary Top model targets built: Model Action Rebuild Reason ===================================================================================================== rtwdemo_reusable_csc 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 16.799s
Для повторного использования буфера, rtwdemo_reusable_csc.c файл содержит следующие глобальные переменные:
static real_T RCSC_IMAG[1048576];
static real_T RCSC_IMAG2[262144];
static real_T RCSC_REAL[1048576];
static real_T RCSC_REAL2[262144];
rtwdemo_reusable_csc.c файл содержит следующий код:
cfile = fullfile(cgDir,... 'rtwdemo_reusable_csc_ert_rtw','rtwdemo_reusable_csc.c'); rtwdemodbtype(cfile,... '/* Output and update for atomic system: ''<Root>/DeltaSubsystem'' */',... '/* Output and update for atomic system: ''<Root>/Downsample'' */',1,0); rtwdemodbtype(cfile,... '/* Model step function */','/* Model initialize function */',1,0);
/* Output and update for atomic system: '<Root>/DeltaSubsystem' */
static void DeltaSubsystem(void)
{
/* SignalConversion generated from: '<S1>/DeltaX' incorporates:
* MATLAB Function: '<S1>/DeltaX'
*/
DeltaX((&(RCSC_REAL2[0])), (&(RCSC_IMAG2[0])), (&(RCSC_REAL[0])),
(&(RCSC_IMAG[0])));
/* SignalConversion generated from: '<S1>/DeltaY' incorporates:
* MATLAB Function: '<S1>/DeltaY'
*/
DeltaY((&(RCSC_REAL[0])), (&(RCSC_IMAG[0])), (&(RCSC_REAL2[0])),
(&(RCSC_IMAG2[0])));
}
/* Model step function */
void rtwdemo_reusable_csc_step(void)
{
int32_T i;
/* ComplexToRealImag: '<Root>/Complex to Real-Imag' incorporates:
* Inport: '<Root>/ComplexData'
*/
for (i = 0; i < 1048576; i++) {
RCSC_REAL[i] = rtU.ComplexData[i].re;
RCSC_IMAG[i] = rtU.ComplexData[i].im;
}
/* End of ComplexToRealImag: '<Root>/Complex to Real-Imag' */
/* MATLAB Function: '<Root>/Downsample' */
Downsample((&(RCSC_REAL[0])), (&(RCSC_IMAG[0])), (&(RCSC_REAL2[0])),
(&(RCSC_IMAG2[0])));
/* Outputs for Atomic SubSystem: '<Root>/DeltaSubsystem' */
DeltaSubsystem();
/* End of Outputs for SubSystem: '<Root>/DeltaSubsystem' */
/* Outport: '<Root>/Out1' incorporates:
* RealImagToComplex: '<Root>/Real-Imag to Complex'
* SignalConversion generated from: '<S1>/DeltaY'
* */
for (i = 0; i < 261121; i++) {
rtY.Out1[i].re = RCSC_REAL2[i];
rtY.Out1[i].im = RCSC_IMAG2[i];
}
/* End of Outport: '<Root>/Out1' */
}
Переменные RCSC_REAL и RCSC_IMAG удерживать выходы блока Complex to Real-Image и DeltaX. Эти переменные содержат входные данные для DeltaY блок. Переменные RCSC_REAL2 и RCSC_IMAG2 удерживать выходы Downsample и DeltaY. Эти переменные содержат входные данные для DeltaX блок. Перемежение буферов таким образом позволяет исключить глобальные переменные в сгенерированном коде.
Для удаления сигнальных объектов из сигнальных линий и регенерации кода в окне команд MATLAB введите следующие команды:
portHandles = get_param(... 'rtwdemo_reusable_csc/Complex to Real-Imag','portHandles'); set_param(portHandles.Outport(1),'MustResolveToSignalObject','off'); set_param(portHandles.Outport(2),'MustResolveToSignalObject','off'); portHandles = get_param(... 'rtwdemo_reusable_csc/Downsample','portHandles'); set_param(portHandles.Outport(1),'MustResolveToSignalObject','off'); set_param(portHandles.Outport(2),'MustResolveToSignalObject','off'); portHandles = get_param(... 'rtwdemo_reusable_csc/DeltaSubsystem/DeltaX','portHandles'); set_param(portHandles.Outport(1),'MustResolveToSignalObject','off'); set_param(portHandles.Outport(2),'MustResolveToSignalObject','off'); portHandles = get_param(... 'rtwdemo_reusable_csc/DeltaSubsystem/DeltaY','portHandles'); set_param(portHandles.Outport(1),'MustResolveToSignalObject','off'); set_param(portHandles.Outport(2),'MustResolveToSignalObject','off'); slbuild(model);
### Starting build procedure for: rtwdemo_reusable_csc ### Successful completion of build procedure for: rtwdemo_reusable_csc Build Summary Top model targets built: Model Action Rebuild Reason ==================================================================================== rtwdemo_reusable_csc 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 11.54s
rtwdemo_reusable_csc.c теперь файл содержит этот код.
cfile = fullfile(cgDir,... 'rtwdemo_reusable_csc_ert_rtw','rtwdemo_reusable_csc.c'); rtwdemodbtype(cfile,... '/* Output and update for atomic system: ''<Root>/DeltaSubsystem'' */',... '/* Output and update for atomic system: ''<Root>/Downsample'' */',1,0); rtwdemodbtype(cfile,... '/* Model step function */','/* Model initialize function */',1,0);
/* Output and update for atomic system: '<Root>/DeltaSubsystem' */
static void DeltaSubsystem(void)
{
/* MATLAB Function: '<S1>/DeltaX' */
DeltaX(rtDWork.z2, rtDWork.z1, rtDWork.z1_m, rtDWork.z2_c);
/* MATLAB Function: '<S1>/DeltaY' */
DeltaY(rtDWork.z1_m, rtDWork.z2_c, &rtDWork.z1[0], &rtDWork.z2[0]);
}
/* Model step function */
void rtwdemo_reusable_csc_step(void)
{
int32_T i;
/* ComplexToRealImag: '<Root>/Complex to Real-Imag' incorporates:
* Inport: '<Root>/ComplexData'
*/
for (i = 0; i < 1048576; i++) {
rtDWork.RCSC_REAL[i] = rtU.ComplexData[i].re;
rtDWork.RCSC_IMAG[i] = rtU.ComplexData[i].im;
}
/* End of ComplexToRealImag: '<Root>/Complex to Real-Imag' */
/* MATLAB Function: '<Root>/Downsample' */
Downsample(rtDWork.RCSC_REAL, rtDWork.RCSC_IMAG, rtDWork.z2, rtDWork.z1);
/* Outputs for Atomic SubSystem: '<Root>/DeltaSubsystem' */
DeltaSubsystem();
/* End of Outputs for SubSystem: '<Root>/DeltaSubsystem' */
/* Outport: '<Root>/Out1' incorporates:
* RealImagToComplex: '<Root>/Real-Imag to Complex'
*/
for (i = 0; i < 261121; i++) {
rtY.Out1[i].re = rtDWork.z1[i];
rtY.Out1[i].im = rtDWork.z2[i];
}
/* End of Outport: '<Root>/Out1' */
}
Сгенерированный код содержит две дополнительные глобальные переменные для удержания входов и выходов блоков.
Примечание.Можно указать повторное использование буфера для сигналов, которые генератор кода не может реализовать. Для этих случаев используйте две диагностики, чтобы указать тип сообщения, отображаемого моделью. В диалоговом окне Параметры конфигурации (Configuration Parameters) этими диагностическими данными являются Обнаружение неиспользуемых пользовательских классов хранения и Обнаружение неоднозначных конечных значений пользовательских классов хранения.
bdclose(model) rtwdemoclean; cd(currentDir)
Чтобы повторно использовать сигнал блока «Единичная задержка» или «Задержка», используйте ту же самую спецификацию повторно используемого класса хранения для пары входных аргументов и аргументов состояния или пары выходных аргументов и аргументов состояния блока «Единичная задержка» или «Задержка». Для блоков задержки необходимо задать для параметра Длина задержки значение 1 и Начальное условие > Источник в Dialog. Для доступа к этим параметрам в модели откройте инспектор свойств и щелкните блок в модели.
Эти ограничения применяются к модели, в которой указано повторное использование буфера для пары корневых сигналов ввода и вывода:
Выходные порты не могут быть условными.
Если генератор кода не может повторно использовать тот же буфер в модели верхнего уровня, созданный код содержит дополнительные буферы. Если верхняя модель является ссылочной, генератор кода сообщает об ошибке. Чтобы устранить ошибку, удалите спецификацию Simulink.signal из сигнала, который подключается к порту вывода.
При запуске исполняемого файла, создаваемого генератором кода, и повторном использовании пары сигналов ввода и вывода корня, когда входное значение корня равно нулю, выходное значение корня также должно быть равно нулю. Если выходное значение не равно нулю и сигналы используются повторно, то результаты моделирования могут отличаться от результатов, получаемых исполняемым файлом.
Может возникнуть несоответствие между моделированием и генерацией кода при назначении одного и того же класса хранения Reusable паре сигналов корневого входа и корневого выхода. Это несоответствие возникает, когда блок Assignment управляет блоком Root Outport, а блок Assignment не присваивает значение каждому элементу выходного сигнала, поскольку порт Y блока Assignment не активен. На этом рисунке показана модель, в которой происходит несоответствие:

Во время моделирования выходные значения неписаного блока назначения равны нулю. Во время генерации кода неписанные выходные значения совпадают с входными.
Эти ограничения применяются к модели, в которой указано повторное использование буфера для сигналов:
Сигналы, указанные для повторного использования, должны иметь одинаковые типы данных и частоты дискретизации.
Для повторного использования буфера, заданного пользователем, блоки, изменяющие сигнал, заданный для повторного использования, должны выполняться перед блоками, использующими исходное значение сигнала. Иногда генератору кода приходится изменять порядок работы блока, чтобы можно было повторно использовать буфер. Для моделей, в которых генератору кода не удается переупорядочить операции блока, повторное использование буфера не происходит.
Для моделей, в которых генератор кода переупорядочивает операции блока таким образом, что Simulink.Signal может произойти повторное использование, можно наблюдать разницу в отсортированном порядке. На вкладке Отладка (Debug) в разделе Диагностика (Diagnostics) выберите стрелку раскрывающегося списка Информационные наложения (Information Overlays). В разделе «Блоки» диалогового окна выберите «Порядок выполнения». Чтобы отобразить сортированный порядок выполнения во время моделирования, на вкладке Моделирование (Modeling) выберите Обновить модель (Update Model). Для отображения порядка выполнения в сгенерированном коде на вкладке C Code выберите Build Model.
Можно указать повторное использование буфера для цепочки повторно используемых подсистем, если эти подсистемы не используются повторно в модели.