В этом примере показано, как использовать 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');
Сконфигурируйте ПИ-контроллер, чтобы использовать переменные 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
команда сконфигурирует модель, чтобы минимизировать компиляции, даже когда компиляция команд запущена в цикле. Модель будет скомпилирована однажды с вызовами operspec
, findop
, и linearize
в цикле.
Запустите цикл и запишите время выполнения с 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
"на" и выполнение пакетного linearize
и findop
команды. Модель будет скомпилирована однажды с вызовами operspec
, findop
, и linearize
.
Запустите и запишите время выполнения с быстрым перезапуском для линейного анализа.
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" 70.54 1 "Batch" 15.42 4.5746 "Fast Restart Loop" 13.24 5.3278 "Fast Restart Batch" 15.92 4.4309
Закройте модель Simulink.
bdclose(mdl);