生成されたコードを使用した MATLAB Compiler で展開されるアプリケーションの高速化
この例では、生成されたコードを使用して、MATLAB® Compiler™ で展開するアプリケーションを高速化する方法を示します。この例では、MATLAB® Coder™ を使用してアルゴリズムの MEX バージョンを生成することでアルゴリズムを高速化します。MATLAB Compiler を使用して、MEX 関数を呼び出すスタンドアロン アプリケーションを展開します。展開されるアプリケーションでは、MATLAB® Runtime を使用します。これにより、MATLAB® をもたないユーザーに使用料なしで展開できるようになります。
このワークフローは、次の場合に役立ちます。
MATLAB Runtime でサポートするプラットフォームにアプリケーションを展開する場合。
アプリケーションに、コード生成に適した計算量の多いアルゴリズムが含まれる場合。
アルゴリズムに対して生成された MEX が元の MATLAB アルゴリズムよりも高速な場合。
アプリケーションの読み取り可能な C/C++ ソース コードを展開する必要がない場合。
この例のアプリケーションでは、DSP System Toolbox™ を必要とする DSP アルゴリズムを使用しています。
MATLAB アプリケーションの作成
高速化するためのベスト プラクティスは、計算量の多いアルゴリズムを、そのアルゴリズムを呼び出すコードから分離することです。
この例では、myRLSFilterSystemIDSim
でアルゴリズムが実装されます。myRLSFilterSystemIDApp
は myRLSFilterSystemIDSim
を呼び出すユーザー インターフェイスを提供します。
myRLSFilterSystemIDSim
は、再帰的最小二乗 (RLS) 適応フィルター処理を使用してシステム同定をシミュレートします。アルゴリズムは dsp.VariableBandwidthFIRFilter
を使用して未同定のシステムをモデル化し、dsp.RLSFilter
を使用して FIR フィルターを識別します。
myRLSFilterSystemIDApp
は、シミュレーション パラメーターを動的に調整するために使用するユーザー インターフェイスを提供します。指定した数のタイム ステップに対して、またはシミュレーションを停止するまでシミュレーションが実行されます。シミュレーションの結果はスコープにプロットされます。
このアプリケーションの詳細については、DSP System Toolbox のドキュメンテーションのRLS 適応フィルター処理を使用したシステム同定 (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 タイム ステップの間、または [シミュレーションの中止] をクリックするまでシミュレーションを実行します。結果はスコープにプロットされます。
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
は、調整情報を保存する構造体をとります。調整構造体の例を定義して、それを -args
オプションを使用して codegen
に渡します。
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. myRLSFilterSystemIDSim
の 100 回の実行時間を測定します。
clear myRLSFilterSystemIDSim disp('Running the MATLAB function ...') tic nTimeSteps = 100; for ind = 1:nTimeSteps myRLSFilterSystemIDSim(ParamStruct); end tMATLAB = toc;
Running the MATLAB function ...
2. myRLSFilterSystemIDSim_mex
の 100 回の実行時間を測定します。
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.9438 seconds Time for MEX function: 0.19591 seconds The MEX function is 9.922 times faster than the original MATLAB function.
MEX コードの最適化
別の C/C++ コンパイラを使用するか、特定のオプションまたは最適化を使用して、より高速な MEX を生成できる場合があります。MATLAB アルゴリズムの高速化を参照してください。
この例では、MEX はこれ以上最適化しなくても十分に高速です。
MEX 関数を呼び出すためのアプリケーションの変更
myRLSFilterSystemIDSim
ではなく myRLSFilterSystemIDSim_mex
が呼び出されるように myRLSFilterSystemIDApp
を変更します。
変更された関数を 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. ツールストリップの [パッケージ化オプション] セクションで、[Web からダウンロードされたランタイム] チェック ボックスが選択されていることを確認します。
このオプションを選択すると、展開された MATLAB アプリケーションで MATLAB Runtime をダウンロードおよびインストールするアプリケーション インストーラーが作成されます。
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 の起動とほぼ同じ時間がかかります。
関連するトピック
- RLS 適応フィルター処理を使用したシステム同定 (DSP System Toolbox)
- MATLAB アルゴリズムを高速化するためのワークフロー
- MATLAB アルゴリズムの高速化
- MATLAB 関数からのスタンドアロン アプリケーションの作成 (MATLAB Compiler)
- MATLAB Runtime について (MATLAB Compiler)
- MATLAB Compiler の「Support for MATLAB and Toolboxes」