Улучшайте линейную аналитическую производительность

Этот пример показывает, как использовать команду fastRestartForLinearAnalysis, чтобы ускорить множественные вызовы компиляции функций в Simulink Control Design, таких как findop и linearize.

Запустите линейные аналитические команды в цикле

В этом примере вы будете обрезать и линеаризовать модель управления скорости вращения двигателя замкнутого цикла. Параметры управления PI отличаются, чтобы наблюдать, как поведение замкнутого цикла изменяется в устойчивом состоянии. Начиная с linearize и findop называется в цикле, модель будет скомпилирована 2*N + 1 раз включая первый вызов operspec.

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

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

Сконфигурируйте контроллер PI, чтобы использовать переменные kp и ki базового рабочего пространства.

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;

Запустите линейные аналитические команды в пакете

Вместо того, чтобы циклично выполняться по параметрам, findop и linearize могут принять, что пакетная структура изменения параметра непосредственно уменьшает число раз, модель скомпилирована. Модель будет скомпилирована 3 раза с вызовами operspec, findop и linearize.

Запустите и запишите время выполнения.

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 сконфигурирует модель, чтобы минимизировать компиляции, даже когда компиляция команд запущена в цикле. Модель будет скомпилирована однажды с вызовами operspec, findop и linearize в цикле.

Запустите цикл и запишите время выполнения с fastRestartForLinearAnalysis "на".

t = cputime;

Включите fastRestartForLinearAnalysis. Обеспечьте 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. Это не скомпилирует модель.

fastRestartForLinearAnalysis(mdl,'off');

Вычислите прошедшее время.

timeElapsedFastRestartLoop = cputime - t;

Запустите Линейные Аналитические Команды в Пакете с fastRestartForLinearAnalysis

Производительность может далее улучшаться путем включения fastRestartForLinearAnalysis и выполнения пакетного linearize и команд findop. Модель будет скомпилирована однажды с вызовами operspec, findop и linearize.

Запустите и запишите время выполнения с быстрым перезапуском для линейного анализа.

t = cputime;

Включите fastRestartForLinearAnalysis. Обеспечьте 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. Это не скомпилирует модель.

fastRestartForLinearAnalysis(mdl,'off');

Вычислите прошедшее время.

timeElapsedFastRestartBatch = cputime - t;

Сравнение результатов

Сравните результаты линеаризации этих 4 методов. Диаграмма Боде ниже показов каждый метод возвращает те же результаты.

Specifiy индексы, чтобы выдержать сравнение.

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"                     62.49               1    
    "Batch"                    12.86          4.8593    
    "Fast Restart Loop"        12.59          4.9635    
    "Fast Restart Batch"       13.43           4.653    

Закройте модель Simulink.

bdclose(mdl);

Смотрите также

| | |