最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

線形解析のパフォーマンスの改善

この例では、fastRestartForLinearAnalysis コマンドを使用して、Simulink Control Design で findoplinearize などのコンパイルを実行する関数の複数回の呼び出しを高速化する方法を説明します。

線形解析コマンドのループ内実行

この例では、閉ループのエンジン速度制御モデルの平衡化と線形化を行います。PI 制御パラメーターを変化させ、定常状態で閉ループ動作がどのように変化するかを観察します。linearize および findop はループ内で呼び出されるため、operspec の初回呼び出しを含め、モデルは 2*N + 1 回コンパイルされます。

エンジン速度制御モデルを開き、モデルから線形解析ポイントを取得します。

mdl = 'scdspeedctrl';
open_system(mdl);
io = getlinio(mdl);
fopt = findopOptions('DisplayReport','off');

ベース ワークスペース変数 kp および ki を使用するように PI コントローラーを設定します。

blk = [mdl,'/PID Controller'];
set_param(blk,'P','kp');
set_param(blk,'I','ki');

変化させるパラメーターのグリッドを作成します。

vp = 0.0005:0.0005:0.003;
vi = 0.0025:0.0005:0.005;
[KP,KI] = ndgrid(vp,vi);
N = numel(KP);
sz = size(KP);

ベース ワークスペース変数を初期化します。

kp = KP(1);
ki = KI(1);

ループを実行して実行時間を記録します。

t = cputime;
ops = operspec(mdl);
for i = N:-1:1
    kp = KP(i);
    ki = KI(i);
    % trim the model
    op = findop(mdl,ops,fopt);
    [j,k] = ind2sub(sz,i);
    % linearize the model
    sysLoop(:,:,j,k) = linearize(mdl,io,op);
end

経過時間を計算します。

timeElapsedLoop = cputime - t;

線形解析コマンドのバッチ実行

パラメーターに対してループを実行する代わりに findoplinearize でバッチ パラメーター変化の構造体を直接受け入れて、モデルがコンパイルされる回数を減らすことができます。モデルは operspecfindop、および linearize の呼び出しで 3 回コンパイルされます。

実行して実行時間を記録します。

t = cputime;
ops = operspec(mdl);

バッチ パラメーター構造体を作成します。

params(1).Name  = 'kp';
params(1).Value =  KP ;
params(2).Name  = 'ki';
params(2).Value =  KI ;

パラメーターのセット全体でモデルを平衡化します。

op = findop(mdl,ops,params,fopt);

パラメーターと操作点のセット全体でモデルを線形化します。

sysBatch = linearize(mdl,io,op,params);

経過時間を計算します。

timeElapsedBatch = cputime - t;

fastRestartForLinearAnalysis を使用した線形解析コマンドのループ内実行

fastRestartForLinearAnalysis コマンドは、コンパイルを実行するコマンドがループ内で実行される場合でも、コンパイルを最小限に抑えるようにモデルを設定します。モデルはループ内での operspecfindop、および linearize の呼び出しで 1 回コンパイルされます。

fastRestartForLinearAnalysis を "on" に指定してループを実行し、実行時間を記録します。

t = cputime;

fastRestartForLinearAnalysis を "on" にします。AnalysisPoints を指定して findop および linearize の呼び出し間でコンパイルを最小限にします。

fastRestartForLinearAnalysis(mdl,'on','AnalysisPoints',io);
ops = operspec(mdl);
for i = N:-1:1
    kp = KP(i);
    ki = KI(i);
    % make sure the block initialization is called after the parameters
    % are updated when the model is in a compiled state
    Simulink.Block.eval(blk);
    % trim the model
    op = findop(mdl,ops,fopt);
    [j,k] = ind2sub(sz,i);
    % linearize the model
    sysFastRestartLoop(:,:,j,k) = linearize(mdl,io,op);
end

fastRestartForLinearAnalysis を "off" にします。こうするとモデルのコンパイルが解除されます。

fastRestartForLinearAnalysis(mdl,'off');

経過時間を計算します。

timeElapsedFastRestartLoop = cputime - t;

fastRestartForLinearAnalysis を使った線形解析コマンドのバッチ実行

fastRestartForLinearAnalysis を "on" にしてバッチの linearize および findop コマンドを実行すると、パフォーマンスをさらに向上させることができます。モデルは operspecfindop、および linearize の呼び出しで 1 回コンパイルされます。

線形解析の高速リスタートをオンにして実行し、実行時間を記録します。

t = cputime;

fastRestartForLinearAnalysis を "on" にします。AnalysisPoints を指定して findop および linearize の呼び出し間でコンパイルを最小限にします。

fastRestartForLinearAnalysis(mdl,'on','AnalysisPoints',io);
ops = operspec(mdl);

バッチ パラメーター構造体を作成します。

params(1).Name  = 'kp';
params(1).Value =  KP ;
params(2).Name  = 'ki';
params(2).Value =  KI ;

パラメーターのセット全体でモデルを平衡化します。

op = findop(mdl,ops,params,fopt);

パラメーターと操作点のセット全体でモデルを線形化します。

sysFastRestartBatch = linearize(mdl,io,op,params);

fastRestartForLinearAnalysis を "off" にします。こうするとモデルのコンパイルが解除されます。

fastRestartForLinearAnalysis(mdl,'off');

経過時間を計算します。

timeElapsedFastRestartBatch = cputime - t;

結果の比較

4 つの方法による線形化の結果を比較します。下記のボード線図は、それぞれの方法で同じ結果が返されることを示しています。

比較するインデックスを指定します。

compareIdx = 1:N;
bode(...
    sysLoop            (:,:,compareIdx),...
    sysBatch           (:,:,compareIdx),...
    sysFastRestartLoop (:,:,compareIdx),...
    sysFastRestartBatch(:,:,compareIdx));
legend(...
    'Loop Linearization'                  ,...
    'Batch Linearization'                 ,...
    'Loop Linearization with Fast Restart',...
    'Batch Linearization with Fast Restart')

各方法について経過時間と高速化の比率を表にまとめます。バッチ平衡化/線形化および fastRestartForLinearAnalysis を使用することにより、パフォーマンスの著しい向上を図ることが可能です。

Method = ["Loop","Batch","Fast Restart Loop","Fast Restart Batch"]';
TimeElapsed = [timeElapsedLoop,timeElapsedBatch,timeElapsedFastRestartLoop,timeElapsedFastRestartBatch]';
SpeedUpFactor = TimeElapsed(1)./TimeElapsed;
TimeElapsedTable = table(Method,TimeElapsed,SpeedUpFactor)
TimeElapsedTable =

  4x3 table

           Method           TimeElapsed    SpeedUpFactor
    ____________________    ___________    _____________

    "Loop"                    164.67               1    
    "Batch"                    49.38          3.3348    
    "Fast Restart Loop"         49.9             3.3    
    "Fast Restart Batch"       47.76          3.4479    

Simulink モデルを閉じます。

bdclose(mdl);

参考

| | |