exponenta event banner

Использование сгенерированного кода для ускорения развертывания приложения с помощью компилятора MATLAB

В этом примере показано, как использовать созданный код для ускорения развертывания приложения с помощью компилятора MATLAB ®. Пример ускоряет алгоритм, используя MATLAB ® Coder™ для создания MEX-версии алгоритма. Для развертывания автономного приложения, вызывающего функцию MEX, используется компилятор MATLAB. В развернутом приложении используется среда выполнения MATLAB ®, которая позволяет выполнять развертывание без лицензионных отчислений для тех, у кого нет MATLAB.

Этот рабочий процесс полезен в следующих случаях:

  • Необходимо развернуть приложение на платформе, поддерживаемой средой выполнения MATLAB.

  • Приложение включает в себя интенсивный в вычислительном отношении алгоритм, который подходит для генерации кода.

  • Генерируемый MEX для алгоритма быстрее исходного алгоритма MATLAB.

  • Для приложения не требуется развертывать читаемый исходный код C/C + +.

В примере приложения используется алгоритм DSP, который требует системного Toolbox™ DSP.

Создание приложения MATLAB

Для ускорения лучше всего отделить интенсивный в вычислительном отношении алгоритм от кода, который его вызывает.

В этом примере: myRLSFilterSystemIDSim реализует алгоритм. myRLSFilterSystemIDApp предоставляет пользовательский интерфейс, вызывающий myRLSFilterSystemIDSim.

myRLSFilterSystemIDSim моделирует идентификацию системы с помощью рекурсивной адаптивной фильтрации методом наименьших квадратов (RLS). Алгоритм использует dsp.VariableBandwidthFIRFilter для моделирования неопознанной системы и dsp.RLSFilter для идентификации фильтра FIR.

myRLSFilterSystemIDApp предоставляет интерфейс пользователя, используемый для динамической настройки параметров моделирования. Моделирование выполняется в течение заданного количества временных шагов или до тех пор, пока моделирование не будет остановлено. Он отображает результаты моделирования в областях.

Дополнительные сведения об этом приложении см. в разделе Идентификация системы с помощью адаптивной фильтрации RLS (DSP System Toolbox) в документации DSP System Toolbox.

В папке, доступной для записи, создайте myRLSFilterSystemIDSim и myRLSFilterSystemIDApp. Чтобы получить доступ к этим файлам, нажмите кнопку «Открыть сценарий».

myRLSFilterSystemIDSim

function [tfe,err,cutoffFreq,ff] = ...
    myRLSFilterSystemIDSim(tuningUIStruct)
% myRLSFilterSystemIDSim implements the algorithm used in
% myRLSFilterSystemIDApp.
% This function instantiates, initializes, and steps through the System
% objects used in the algorithm.
%
% You can tune the cutoff frequency of the desired system and the
% forgetting factor of the RLS filter through the GUI that appears when
% myRLSFilterSystemIDApp is executed.

%   Copyright 2013-2017 The MathWorks, Inc.

%#codegen

% Instantiate and initialize System objects. The objects are declared
% persistent so that they are not recreated every time the function is
% called inside the simulation loop.
persistent rlsFilt sine unknownSys transferFunctionEstimator
if isempty(rlsFilt)
    % FIR filter models the unidentified system
    unknownSys = dsp.VariableBandwidthFIRFilter('SampleRate',1e4,...
        'FilterOrder',30,...
        'CutoffFrequency',.48 * 1e4/2);
    % RLS filter is used to identify the FIR filter
    rlsFilt = dsp.RLSFilter('ForgettingFactor',.99,...
        'Length',28);
    % Sine wave used to generate input signal
    sine = dsp.SineWave('SamplesPerFrame',1024,...
        'SampleRate',1e4,...
        'Frequency',50);
    % Transfer function estimator used to estimate frequency responses of
    % FIR and RLS filters.
    transferFunctionEstimator = dsp.TransferFunctionEstimator(...
        'FrequencyRange','centered',...
        'SpectralAverages',10,...
        'FFTLengthSource','Property',...
        'FFTLength',1024,...
        'Window','Kaiser');
end

if tuningUIStruct.Reset
    % reset System objects
    reset(rlsFilt);
    reset(unknownSys);
    reset(transferFunctionEstimator);
    reset(sine);
end

% Tune FIR cutoff frequency and RLS forgetting factor
if  tuningUIStruct.ValuesChanged
    param = tuningUIStruct.TuningValues;
    unknownSys.CutoffFrequency  = param(1);
    rlsFilt.ForgettingFactor = param(2);
end
    
% Generate input signal - sine wave plus Gaussian noise
inputSignal = sine() +  .1 * randn(1024,1);

% Filter input though FIR filter
desiredOutput = unknownSys(inputSignal);

% Pass original and desired signals through the RLS Filter
[rlsOutput , err] = rlsFilt(inputSignal,desiredOutput);

% Prepare system input and output for transfer function estimator
inChans = repmat(inputSignal,1,2);
outChans = [desiredOutput,rlsOutput];

% Estimate transfer function
tfe = transferFunctionEstimator(inChans,outChans);

% Save the cutoff frequency and forgetting factor
cutoffFreq = unknownSys.CutoffFrequency;
ff = rlsFilt.ForgettingFactor;

end

myRLSFilterSystemIDApp

function scopeHandles = myRLSFilterSystemIDApp(numTSteps)
% myRLSFilterSystemIDApp initialize and execute RLS Filter
% system identification example. Then, display results using
% scopes. The function returns the handles to the scope and UI objects.
%
% Input:
%   numTSteps - number of time steps
% Outputs:
%   scopeHandles    - Handle to the visualization scopes

% Copyright 2013-2017 The MathWorks, Inc.


if nargin == 0
    numTSteps = Inf; % Run until user stops simulation.
end

% Create scopes
tfescope = dsp.ArrayPlot('PlotType','Line',...
    'Position',[8 696 520 420],...
    'YLimits',[-80 30],...
    'SampleIncrement',1e4/1024,...
    'YLabel','Amplitude (dB)',...
    'XLabel','Frequency (Hz)',...
    'Title','Desired and Estimated Transfer Functions',...
    'ShowLegend',true,...
    'XOffset',-5000);

msescope = timescope('SampleRate',1e4,...
    'Position',[8 184 520 420],...
    'TimeSpanSource','property','TimeSpan',0.01,...
    'YLimits',[-300 10],'ShowGrid',true,...
    'YLabel','Mean-Square Error (dB)',...
    'Title','RLSFilter Learning Curve');

screen = get(0,'ScreenSize');
outerSize = min((screen(4)-40)/2, 512);
tfescope.Position = [8, screen(4)-outerSize+8, outerSize+8,...
    outerSize-92];
msescope.Position = [8, screen(4)-2*outerSize+8, outerSize+8, ...
    outerSize-92];

% Create UI to tune FIR filter cutoff frequency and RLS filter
%  forgetting factor
Fs = 1e4;
param = struct([]);
param(1).Name = 'Cutoff Frequency (Hz)';
param(1).InitialValue = 0.48 * Fs/2;
param(1).Limits = Fs/2 * [1e-5, .9999];
param(2).Name = 'RLS Forgetting Factor';
param(2).InitialValue = 0.99;
param(2).Limits = [.3, 1];
hUI = HelperCreateParamTuningUI(param, 'RLS FIR Demo');
set(hUI,'Position',[outerSize+32, screen(4)-2*outerSize+8, ...
    outerSize+8, outerSize-92]);

% Execute algorithm
while(numTSteps>=0)
    
    S = HelperUnpackUIData(hUI);

    drawnow limitrate;   % needed to process UI callbacks
    
    [tfe,err] = myRLSFilterSystemIDSim(S);
    
    if S.Stop     % If "Stop Simulation" button is pressed
        break;
    end
    if S.Pause
        continue;
    end
    
    % Plot transfer functions
    tfescope(20*log10(abs(tfe)));
    % Plot learning curve
    msescope(10*log10(sum(err.^2)));
    numTSteps = numTSteps - 1;
end

if ishghandle(hUI)  % If parameter tuning UI is open, then close it.
    delete(hUI);
    drawnow;
    clear hUI
end

scopeHandles.tfescope = tfescope;
scopeHandles.msescope = msescope;
end

Тестирование приложения MATLAB

Запустите приложение идентификации системы в течение 100 шагов времени. Приложение выполняет моделирование в течение 100 шагов времени или до тех пор, пока не будет нажата кнопка Остановить моделирование (Stop Simulation). Результаты отображаются в областях.

scope1 = myRLSFilterSystemIDApp(100);
release(scope1.tfescope);
release(scope1.msescope);

Подготовить алгоритм для ускорения

При использовании кодера MATLAB для ускорения алгоритма MATLAB код должен подходить для генерации кода.

1. Убедитесь, что myRLSFilterSystemIDSim.m включает в себя %#codegen после подписи функции.

Эта директива указывает на необходимость создания кода для функции. В редакторе MATLAB он позволяет анализатору кода обнаруживать проблемы генерации кода.

2. Проверьте алгоритм для неподдерживаемых функций или конструкций.

coder.screener('myRLSFilterSystemIDSim');

Средство готовности к созданию кода не находит проблем с созданием кода в этом алгоритме.

Ускорение алгоритма

Для ускорения алгоритма в этом примере используется кодер MATLAB codegen команда. Кроме того, можно использовать приложение Кодер MATLAB. Для создания кода необходимо указать тип, размер и сложность входных аргументов. Функция myRLSFilterSystemIDSim принимает структуру, в которой хранится информация о настройке. Определите пример структуры настройки и передайте ее в codegen с помощью -args вариант.

ParamStruct.TuningValues = [2400 0.99];
ParamStruct.ValuesChanged = false;
ParamStruct.Reset = false;
ParamStruct.Pause = false;
ParamStruct.Stop  = false;
codegen myRLSFilterSystemIDSim -args {ParamStruct};
Code generation successful.

codegen создает функцию MEX myRLSFilterSystemIDSim_mex в текущей папке.

Сравнение функций MEX и MATLAB

1. Время 100 казней myRLSFilterSystemIDSim.

clear myRLSFilterSystemIDSim
disp('Running the MATLAB function ...')
tic
nTimeSteps = 100;
for ind = 1:nTimeSteps
     myRLSFilterSystemIDSim(ParamStruct);
end
tMATLAB = toc;
Running the MATLAB function ...

2. Время 100 казней myRLSFilterSystemIDSim_mex.

clear myRLSFilterSystemIDSim
disp('Running the MEX function ...')
tic
for ind = 1:nTimeSteps
    myRLSFilterSystemIDSim_mex(ParamStruct);
end
tMEX = toc;

disp('RESULTS:')
disp(['Time for original MATLAB function: ', num2str(tMATLAB),...
     ' seconds']);
disp(['Time for MEX function: ', num2str(tMEX), ' seconds']);
disp(['The MEX function is ', num2str(tMATLAB/tMEX),...
    ' times faster than the original MATLAB function.']);
Running the MEX function ...
RESULTS:
Time for original MATLAB function: 1.8853 seconds
Time for MEX function: 0.29186 seconds
The MEX function is 6.4595 times faster than the original MATLAB function.

Оптимизация кода MEX

Иногда можно создать более быстрый MEX, используя другой компилятор C/C + + или используя определенные опции или оптимизации. См. раздел Ускорение алгоритмов MATLAB.

Для этого примера MEX является достаточно быстрым без дальнейшей оптимизации.

Изменение приложения для вызова функции MEX

Изменить myRLSFilterSystemIDApp чтобы он вызывал myRLSFilterSystemIDSim_mex вместо myRLSFilterSystemIDSim.

Сохранить измененную функцию в myRLSFilterSystemIDApp_acc.m.

Тестирование приложения с помощью ускоренного алгоритма

clear myRLSFilterSystemIDSim_mex;
scope2 = myRLSFilterSystemIDApp_acc(100);
release(scope2.tfescope);
release(scope2.msescope);

Поведение приложения, вызывающего функцию MEX, совпадает с поведением приложения, вызывающего исходную функцию MATLAB. Однако графики обновляются быстрее, поскольку моделирование выполняется быстрее.

Создание автономного приложения

1. Чтобы открыть приложение компилятора приложений, на вкладке Приложения в разделе Развертывание приложений щелкните значок приложения.

2. Укажите, что основным файлом является myRLSFilterSystemIDApp_acc.

Приложение определяет необходимые файлы для этого приложения. Приложение может найти файлы MATLAB и MEX-файлы, используемые приложением. При необходимости необходимо добавить другие типы файлов, например MAT-файлы или изображения.

3. Убедитесь, что в разделе «Параметры упаковки» на панели инструментов установлен флажок «Среда выполнения, загруженная из Интернета».

Этот параметр создает установщик приложения, который загружает и устанавливает среду выполнения MATLAB с развернутым приложением MATLAB.

4. Щелкните Пакет (Package) и сохраните проект.

5. В окне Пакет убедитесь, что установлен флажок Открыть папку вывода по завершении процесса.

По завершении упаковки открывается папка вывода.

Установка приложения

1. Откройте окно for_redistribution папка.

2. Управляемый MyAppInstaller_web.

3. При подключении к Интернету с помощью прокси-сервера введите параметры сервера.

4. Перейдите на страницы мастера установки.

  • На странице «Параметры установки» используйте папку установки по умолчанию.

  • На странице Обязательное программное обеспечение используйте папку установки по умолчанию.

  • На странице Лицензионное соглашение прочитайте лицензионное соглашение и примите лицензию.

  • На странице подтверждения нажмите кнопку Установить.

Если среда выполнения MATLAB еще не установлена, программа установки установит ее.

5. Нажмите кнопку Готово (Finish).

Запустить приложение

1. Откройте окно терминала.

2. Перейдите в папку, в которой установлено приложение.

  • Для Windows ® перейдите кC:\Program Files\myRLSFilterSystemIDApp_acc.

  • Для macOS перейдите к /Applications/myRLSFilterSystemIDApp_acc.

  • Для Linux перейдите к /usr/myRLSFilterSystemIDApp_acc.

3. Запустите приложение с помощью соответствующей команды для вашей платформы.

  • Для Windows используйте application\myRLSFilterSystemIDApp_acc.

  • Для macOS используйте myRLSFilterSystemIDApp_acc.app/Contents/MacOS/myRLSFilterSystemIDApp_acc.

  • Для Linux используйте /myRLSFilterSystemIDApp_acc.

Запуск приложения занимает примерно то же время, что и запуск MATLAB.

Связанные темы