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

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

Этот рабочий процесс полезен, когда:

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

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

  • Сгенерированный MEX для алгоритма быстрее, чем исходный алгоритм MATLAB.

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

В примере приложения используется Алгоритм ЦОС, которая требует DSP System Toolbox™.

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

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

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

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

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

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

В папке с возможностью записи создайте myRLSFilterSystemIDSim и myRLSFilterSystemIDApp. Кроме того, чтобы получить доступ к этим файлам, нажмите Open Script.

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 Coder, чтобы ускорить алгоритм MATLAB, код должен быть подходящим для генерации кода.

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

Эта директива указывает, что вы намерены сгенерировать код для функции. В РЕДАКТОРА MATLAB он позволяет анализатору кода обнаруживать проблемы генерации кода.

2. Отобразите алгоритм на наличие неподдерживаемых функций или конструкций.

coder.screener('myRLSFilterSystemIDSim');

Инструмент готовности генерации кода не находит проблем генерации кода в этом алгоритме.

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

Чтобы ускорить алгоритм, этот пример использует MATLAB Coder codegen команда. Также можно использовать приложение MATLAB Coder. Для генерации кода необходимо указать тип, размер и сложность входных параметров. Функция 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.

Протестируйте приложение с помощью алгоритма Accelerated

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

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

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

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

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

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

3. В разделе «Опции упаковки» панели инструментов убедитесь, что установлен флажок Runtime downloaded from web.

Эта опция создаёт программу установки приложения, которая загружает и устанавливает MATLAB Runtime с помощью развернутого приложения MATLAB.

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

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

Когда упаковка будет завершена, откроется папка выхода.

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

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

2. Выполняйте MyAppInstaller_web.

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

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

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

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

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

  • На странице Подтверждение нажмите Установить.

Если MATLAB Runtime еще не установлен, инсталлятор устанавливает его.

5. Нажмите Конец.

Запуск приложения

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.

Похожие темы