Используйте сгенерированный код, чтобы ускорить приложение, развернутое с MATLAB Compiler

В этом примере показано, как использовать сгенерированный код, чтобы ускорить приложение, которое вы развертываете с Компилятором MATLAB®. Пример ускоряет алгоритм при помощи MATLAB® Coder™, чтобы сгенерировать версию 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 обеспечивает пользовательский интерфейс, который вы используете, чтобы динамически настроить параметры симуляции. Это запускает симуляцию для конкретного количества временных шагов или пока вы не останавливаете симуляцию. Это строит результаты на осциллографах.

Для получения дополнительной информации об этом приложении, смотрите, что System Identification Использует Адаптивную Фильтрацию 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 = dsp.TimeScope('SampleRate',1e4,'TimeSpan',.01,...
    'Position',[8 184 520 420],...
    '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);
Warning: MATLAB Connector is not running. 
Warning: MATLAB Connector is not running. 

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

Когда вы используете 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};

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: 2.2767 seconds
Time for MEX function: 0.32429 seconds
The MEX function is 7.0206 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. Чтобы открыть Приложение Application Compiler, на вкладке Apps, при Развертывании приложения, кликают по значку приложения.

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

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

3. В разделе Packaging Options панели инструментов убедитесь, что Время выполнения, загруженное с веб-флажка, выбрано.

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

4. Нажмите Package и сохраните проект.

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

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

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

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

2. Запустите MyAppInstaller_web.

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

4. Совершенствуйтесь через страницы мастера установки.

  • На странице Installation Options используйте папку стандартной установки.

  • На странице Required Software используйте папку стандартной установки.

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

  • На странице Confirmation нажмите Install.

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

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.

Похожие темы