Если ваша модель имеет оптимальные установки параметров для удаления копий данных, вы можете смочь удалить дополнительные копии данных при помощи Reusable
класс памяти на сигналах через редактор Отображений Кода или Simulink.Signal
объекты данных. Эта оптимизация уменьшает копии данных и потребление памяти и скорость выполнения кода увеличений. После изучения сгенерированного кода и Статического Метрического Отчета Кода и идентификации областей, где вы думаете, буферное повторное использование возможно, вы задаете Reusable
класс памяти на сигнальных линиях.
Можно задать буферное повторное использование на сигналах, которые включают пару корневого импорта и сигналов выходного порта. Можно также задать буферное повторное использование на только паре корневого импорта и сигналов выходного порта. Эта оптимизация уменьшает ROM и потребление RAM, потому что существуют менее глобальные переменные и копии данных в сгенерированном коде. Скорость выполнения кода также увеличивается.
Модель ex_reusable_csc
содержит подсистему одноразового использования DeltaSubsystem
и блок MATLAB function Downsample
. DeltaSubsystem
содержит блоки MATLAB function DeltaX
и DeltaY
.
model ='ex_reusable_csc';
open_system(model);
Откройте приложение Embedded Coder.
Чтобы открыть редактор Отображений Кода, нажмите Code Interface> Individual Element Code Mappings.
В модели выберите RCSC_REAL
сигнальная линия. Чтобы просмотреть этот сигнал или любой сигнал в редакторе Отображений Кода, на вкладке Signals/States, нажимают, Add выбрал сигналы закодировать кнопку отображений.
Для строки, которая представляет сигнальную линию, устанавливает столбец Класса памяти на Reusable
.
Similary, добавляют эти сигналы в редактор Отображений Кода и устанавливают Класс памяти на Reusable
:
RCSC_IMAG
RCSC_REAL2
RCSC_IMAG2
И эти сигналы в подсистеме:
RCSC_REAL
RCSC_IMAG
RCSC_REAL2
RCSC_IMAG2
В качестве альтернативы используйте эти команды в командном окне MATLAB:
cmo = coder.mapping.utils.create(model); cm = coder.mapping.api.get(model); portHandles = get_param(... 'ex_reusable_csc/Complex to Real-Imag','portHandles'); addSignal(cm,[portHandles.Outport(1),portHandles.Outport(2)],... 'StorageClass','Reusable'); portHandles = get_param(... 'ex_reusable_csc/Downsample','portHandles'); addSignal(cm,[portHandles.Outport(1),portHandles.Outport(2)],... 'StorageClass','Reusable'); portHandles = get_param(... 'ex_reusable_csc/DeltaSubsystem/DeltaX','portHandles'); addSignal(cm,[portHandles.Outport(1),portHandles.Outport(2)],... 'StorageClass','Reusable'); portHandles = get_param(... 'ex_reusable_csc/DeltaSubsystem/DeltaY','portHandles'); addSignal(cm,[portHandles.Outport(1),portHandles.Outport(2)],... 'StorageClass','Reusable');
Создайте модель.
currentDir = pwd; [~,cgDir] = rtwdemodir(); slbuild(model);
### Starting build procedure for: ex_reusable_csc ### Successful completion of build procedure for: ex_reusable_csc Build Summary Top model targets built: Model Action Rebuild Reason ================================================================================================ ex_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 22.477s
Для буферного повторного использования, ex_reusable_csc.c
файл содержит эти глобальные переменные:
cfile = fullfile(cgDir,... 'ex_reusable_csc_ert_rtw','ex_reusable_csc.c'); rtwdemodbtype(cfile,... '/* Definition for custom storage class: Reusable */',... '/* External inputs (root inport signals with default storage) */',1,0);
/* Definition for custom storage class: Reusable */ static real_T RCSC_IMAG[1048576]; /* '<Root>/Complex to Real-Imag' */ static real_T RCSC_IMAG2[262144]; /* '<Root>/Downsample' */ static real_T RCSC_REAL[1048576]; /* '<Root>/Complex to Real-Imag' */ static real_T RCSC_REAL2[262144]; /* '<Root>/Downsample' */
ex_reusable_csc.c
файл содержит этот код:
cfile = fullfile(cgDir,... 'ex_reusable_csc_ert_rtw','ex_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) { /* ComplexToRealImag: '<Root>/Complex to Real-Imag' incorporates: * MATLAB Function: '<S1>/DeltaX' * SignalConversion generated from: '<S1>/DeltaX' * */ DeltaX((&(RCSC_REAL2[0])), (&(RCSC_IMAG2[0])), (&(RCSC_REAL[0])), (&(RCSC_IMAG[0]))); /* SignalConversion generated from: '<Root>/Downsample' incorporates: * ComplexToRealImag: '<Root>/Complex to Real-Imag' * MATLAB Function: '<S1>/DeltaY' * SignalConversion generated from: '<S1>/DeltaY' * */ DeltaY((&(RCSC_REAL[0])), (&(RCSC_IMAG[0])), (&(RCSC_REAL2[0])), (&(RCSC_IMAG2[0]))); } /* Model step function */ void ex_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
блок. Путем перемежения буферов таким образом, вы устраняете избыточные копии данных в сгенерированном коде.
Чтобы удалить сигналы из редактора Отображений Кода, на вкладке Signals/States, выбирают сигналы и нажимают, Remove выбрал сигналы закодировать кнопку отображений.
В качестве альтернативы используйте эти команды в командном окне MATLAB:
portHandles = get_param(... 'ex_reusable_csc/Complex to Real-Imag','portHandles'); removeSignal(cm,[portHandles.Outport(1),portHandles.Outport(2)]); portHandles = get_param(... 'ex_reusable_csc/Downsample','portHandles'); removeSignal(cm,[portHandles.Outport(1),portHandles.Outport(2)]); portHandles = get_param(... 'ex_reusable_csc/DeltaSubsystem/DeltaX','portHandles'); removeSignal(cm,[portHandles.Outport(1),portHandles.Outport(2)]); portHandles = get_param(... 'ex_reusable_csc/DeltaSubsystem/DeltaY','portHandles'); removeSignal(cm,[portHandles.Outport(1),portHandles.Outport(2)]);
Когда вы генерируете код для модели, ex_reusable_csc.h
содержит две дополнительных глобальных переменные:
slbuild(model); cfile = fullfile(cgDir,... 'ex_reusable_csc_ert_rtw','ex_reusable_csc.h'); rtwdemodbtype(cfile,... '/* Block signals and states',... '} D_Work;',1,0);
### Starting build procedure for: ex_reusable_csc ### Successful completion of build procedure for: ex_reusable_csc Build Summary Top model targets built: Model Action Rebuild Reason =============================================================================== ex_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.873s /* Block signals and states (default storage) for system '<Root>' */ typedef struct { real_T z2[262144]; /* '<S1>/DeltaY' */ real_T z1[262144]; /* '<S1>/DeltaY' */ real_T z1_m[261632]; /* '<S1>/DeltaX' */ real_T z2_c[261632]; /* '<S1>/DeltaX' */ real_T RCSC_REAL[1048576]; /* '<Root>/Complex to Real-Imag' */ real_T RCSC_IMAG[1048576]; /* '<Root>/Complex to Real-Imag' */
ex_reusable_csc.c
файл теперь содержит этот код.
cfile = fullfile(cgDir,... 'ex_reusable_csc_ert_rtw','ex_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 ex_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' */ }
Сгенерированный код содержит две дополнительных глобальных переменные для содержания вводов и выводов блока.
Для снова использованных элементов данных можно задать то же значение для свойства Identifier. Если вы не задаете значение для Идентификатора, генератор кода использует ту же метку сигнала, чтобы назвать допускающий повторное использование сигнал в сгенерированном коде. Генератор кода не снова использует сигналы если:
Сигналы имеют те же метки, но различные идентификаторы.
Сигналы имеют тот же идентификатор, но различные значения для этих свойств: DataScope, HeaderFile, DefinitionFile и Владелец. Если существует несоответствие в каком-либо из свойств, генератор кода останавливает и производит ошибку, если параметр конфигурации модели Обнаруживает неснова использованные пользовательские классы памяти, установлен в error
.
1. Откройте модель rtwdemo_reusable
.
model ='rtwdemo_reusable_csc';
open_system(model);
2. Сигналы в твердости модели к соответствующему Simulink.Signal
объекты данных в Базовом рабочем пространстве. Щелкните правой кнопкой по RCSC_REAL
сигнальная линия. Из контекстного меню выберите Properties. В диалоговом окне Signal Properties смотрите это, именем сигнала является RCSC_REAL
и имя Сигнала параметра должно решить к объекту Сигнала Simulink, выбран. Эта установка указывает, что существует Simulink.Signal
объект данных в Базовом рабочем пространстве с тем же именем как RCSC_REAL
.
3. В модели перейдите в DeltaSubsystem
подсистема. Выберите RCSC_REAL
сигнальная линия в этой подсистеме. Этот сигнал также решает к объекту сигнала в Базовом рабочем пространстве.
4. В Базовом рабочем пространстве, дважды щелкают по объекту данных RCSC_REAL
. Simulink.Signal
диалоговое окно открывается.
5. На вкладке Code Generation смотрите это, параметр Класса памяти устанавливается на Reusable
. Эта установка дает генератору кода команду генерировать код для сигнала как глобальная переменная под названием RCSC_REAL
. С Reusable
класс памяти, сгенерированный код может сохранить выход блока Complex to Real-Imag (на корневом уровне модели) и выход блока MATLAB function DeltaX
(в подсистеме) в RCSC_REAL
глобальная переменная.
6. В галерее Apps, под Генерацией кода, нажимают Embedded Coder. Вкладка C Code открывается.
7. Нажмите кнопку Build.
Сгенерированный код достигает тех же результатов как предыдущий рабочий процесс, где вы добавляете сигналы в редактор Отображений Кода и устанавливаете Класс памяти на Reusable
.
Примечание: можно задать буферное повторное использование на сигналах, что генератор кода не может реализовать. Для тех случаев используйте две диагностики, чтобы задать тип сообщения, который отображает модель. В диалоговом окне Configuration Parameters эта диагностика, Обнаруживают неснова использованные пользовательские классы памяти и Обнаруживают неоднозначные пользовательские окончательные значения класса памяти.
bdclose(model) rtwdemoclean; cd(currentDir)
Чтобы снова использовать сигнал блока Unit Delay или Delay, используйте ту же допускающую повторное использование спецификацию класса памяти для пары входа и утвердите аргументы или пару выхода и утвердите аргументы Unit Delay или блока Delay. Для блоков Задержки необходимо установить параметр длины Задержки на 1
и Начальное условие> Источник к Dialog
. Чтобы получить доступ к этим параметрам, в модели, открывают Property Inspector и кликают по блоку в модели.
Эти ограничения применяются к модели, в которой вы задаете буферное повторное использование для пары корневого импорта и сигналов выходного порта:
Выходные порты не могут быть условным выражением.
Если генератор кода не может снова использовать тот же буфер в топ-модели, сгенерированный код содержит дополнительные буферы. Если топ-модель является моделью, на которую ссылаются, генератор кода сообщает об ошибке. Чтобы разрешить ошибку, удалите Simulink.Signal
спецификация от сигнала, который соединяется с портом выходного порта.
Когда вы запускаете исполняемый файл, который производит генератор кода, и вы снова используете пару корневого импорта и сигналов выходного порта, когда корневое входное значение является нулем, корневое выходное значение должно также быть нулем. Если выходное значение является ненулевым, и вы снова используете сигналы, то результаты симуляции могут отличаться от результатов, к которым приводит исполняемый файл.
Может быть симуляция по сравнению с несоответствием генерации кода, когда вы присваиваете тот же Допускающий повторное использование класс памяти паре корневого импорта и корневых сигналов выходного порта. Это несоответствие происходит, когда блок Assignment управляет блоком Root Outport, и блок Assignment не присваивает значение каждому элементу выходного сигнала, потому что порт Y блока Assignment не активен. Это изображение показывает модель, в которой происходит несоответствие:
В процессе моделирования незаписанные выходные значения блока Assignment являются нулем. Во время генерации кода незаписанные выходные значения совпадают с входом.
Эти ограничения применяются к модели, в которой вы задаете буферное повторное использование для сигналов при помощи Simulink.Signal
объект данных:
Сигналы, что вы задаете для повторного использования, должны иметь совпадающие типы данных и частоты дискретизации.
Для заданного пользователями буферного повторного использования блоки, которые изменяют сигнал, заданный для повторного использования, должны выполниться перед блоками, которые используют исходное значение сигналов. Иногда генератор кода должен изменить порядок блочной операции так, чтобы буферное повторное использование могло произойти. Для моделей, в которых генератор кода не может переупорядочить блочные операции, не происходит буферное повторное использование.
Для моделей, в которых генератор кода переупорядочивает блочные операции так, чтобы Simulink.Signal
повторное использование может произойти, можно наблюдать различие в отсортированном порядке. На вкладке Debug, в разделе Diagnostics выбирают Information Overlays выпадающая стрела. В разделе Blocks диалогового окна выберите Execution Order. Чтобы отобразить отсортированный порядок выполнения в процессе моделирования, на вкладке Modeling, выбирают Update Model. Чтобы отобразить порядок выполнения в сгенерированном коде, на вкладке C Code, выбирают Build Model.
Можно задать буферное повторное использование для цепи допускающих повторное использование подсистем, пока эти подсистемы не становятся снова использованными нигде в модели.