MATLAB Answers

How to speed up simulation containing multiple for Loops?

15 views (last 30 days)
omer
omer on 14 Jun 2016
Commented: omer on 21 Jun 2016
I have a script :
for (DBuck_On = 0.99:-0.09:0.01)
for (Mode_Control=0:1:3)
for(DT_Comp_Mode=0:1:3)
for(Fs=50e3:50e3:200e3)
for(DT_On = -500e-9:50e-9:500e-9)
for(DT_Off =-500e-9:50e-9:500e-9)
for (T_On_Min = 50e-9 : 50e-9 : 250e-9)
for (T_Off_Min = 50e-9 : 50e-9 : 250e-9)
for (Aux_Control = 0:1)
for (T_Aux_On_Min = [50e-9 60e-9] )
for (T_Aux_Off_Min = [50e-9 60e-9] )
for( DT_Aux_On =[50e-9 100e-9 200e-9])
for ( DT_Aux_Off =[50e-9 100e-9 200e-9])
Ts=1/Fs;
DBuck_Off = 1-DBuck_On;
if (Mode_Control==1)
DBuck_Off=0.5-DBuck_On/2;
end
D1=DBuck_On;
D2=DBuck_Off;
D3=1-DBuck_On-DBuck_Off;
sim('DPWMIgalSimulation_Comparison_RoiVersion_Vs_MyVersion');
MyRawData = csvread(strcat(pwd,'\MyTempTestVector.csv'));
RoiRawData = csvread(strcat(pwd,'\RoiTempTestVector.csv'));
if (~isequal(MyRawData,RoiRawData))
if(Flag)
MyData=MyRawData;
RoiData=RoiRawData;
Flag=false;
continue;
end
MyData=[MyData;MyRawData]
RoiData=[RoiData;RoiRawData]
end
end
end
end
end
end
end
end
end
end
end
end
end
end
I the simulation recieves the input(DbuckOn, Mode,DT...) and output single vector , into MyRawData/RoiRawData then i accumulate vectors that are not the same in two Databases :MyData and RoiData. This Data i will save in CSV. Is there a way to use all processors cores in order to execute the for loops faster? I tried parfor but it seems not to work(I use Matlab2016 trial). Any other suggestions for speed optimizations? Thank you

  0 Comments

Sign in to comment.

Answers (2)

Titus Edelhofer
Titus Edelhofer on 14 Jun 2016
Hi,
you should be able to use parfor for such problems, see e.g. this example.
In addition, I would suggest to replace your many loops by ndgrid, something like
[DBuck_OnVec, Mode_ControlVec, DT_Comp_ModeVec] = ndgrid(0.99:-0.09:0.01, 0:3, 0:3);
parfor cnt = 1:numel(DBuck_On)
DBuck_On = DBuck_OnVec(cnt);
...
sim(...)
end
Titus

  3 Comments

omer
omer on 14 Jun 2016
Hey Titus, Thanks for your answer. I changed the first loop to parfor. And i changed the implementation a bit. Now i read the csv's created by the simulation . I check a condition (iseqaul) and want to save the Raw Csv data into the cellarray (every cycle of loops the cell array cell number is increasing). But i still get errors :
the script:
parfor (k=1:length(DBuck_On))
for (Mode_Control=0:1:3)
for(DT_Comp_Mode=0:1:3)
for(Fs=50e3:50e3:200e3)
for(DT_On = -500e-9:50e-9:500e-9)
for(DT_Off =-500e-9:50e-9:500e-9)
for (T_On_Min = 50e-9 : 50e-9 : 250e-9)
for (T_Off_Min = 50e-9 : 50e-9 : 250e-9)
for (Aux_Control = 0:1)
for (T_Aux_On_Min = [50e-9 60e-9] )
for (T_Aux_Off_Min = [50e-9 60e-9] )
for( DT_Aux_On =[50e-9 100e-9 200e-9])
for ( DT_Aux_Off =[50e-9 100e-9 200e-9])
Ts=1/Fs;
DBuck_Off = 1-DBuck_On(k);
if (Mode_Control==1)
DBuck_Off=0.5-DBuck_On(k)/2;
end
D1=DBuck_On(k);
D2=DBuck_Off;
D3=1-DBuck_On(k)-DBuck_Off;
sim('DPWMIgalSimulation_Comparison_RoiVersion_Vs_MyVersion');
MyRawData = csvread(strcat(pwd,'\MyTempTestVector.csv'));
RoiRawData = csvread(strcat(pwd,'\RoiTempTestVector.csv'));
if (~isequal(MyRawData,RoiRawData))
MyData{Ind}={MyRawData};
RoiData{Ind}={RoiRawData};
Ind=Ind+1;
and the errors is about the parfor : 'valid indices for "MyData" is restricted in parfor loops' 'valid indices for "RoiData" is restricted in parfor loops'
Titus Edelhofer
Titus Edelhofer on 16 Jun 2016
Hi,
that's right. The different workers would need to synchronize, what the current value of Ind is and therefore loop iterations would not be independent.
You could do the following
MyData = cell(1, length(DBuck_On));
RoiData = cell(1, length(DBuck_On));
parfor k=1:length(DBuck_On)
MyData{k} = {};
RoiData{k} = {};
...
if ~isequal(...)
MyData{k}{end+1} = MyRawData;
RoiData{k}{end+1} = RoiRawData;
end
end
This way you would end up with cell arrays of cell arrays, which you could combine again into one:
MyData = [MyData{:}];
Titus
omer
omer on 16 Jun 2016
Hey Titus, thanks again. I changed the code , and now im doing ndgrid in order to save all data in matrix and use only one loop :
clear all;
Dir=pwd;
% Simulation Run
SimTime = 0; % Ts full simulation
N = 1e5;
SampleTime = SimTime/N;
MyFileName=strcat(pwd,'\MyTestVec');
RoiFileName=strcat(pwd,'\RoiTestVec');
%CCM Mode
DBuck_On = 0.99:-0.09:0.01;
Mode_Control=[0 1 2 3];
DT_Comp_Mode=[0 1 2 3];
Fs=50e3:50e3:200e3;
DT_On = -100e-9:50e-9:100e-9;
DT_Off =-100e-9:50e-9:100e-9;
T_On_Min = 50e-9 : 50e-9 : 250e-9;
T_Off_Min = 50e-9 : 50e-9 : 250e-9;
Aux_Control = [0 1];
T_Aux_On_Min = [50e-9 60e-9] ;
T_Aux_Off_Min = [50e-9 60e-9] ;
DT_Aux_On =[50e-9 100e-9 200e-9];
DT_Aux_Off =[50e-9 100e-9 200e-9];
[XDBuck_On,XMode_Control,XDT_Comp_Mode,XFs,XDT_On,XDT_Off,XT_On_Min,XT_Off_Min,XAux_Control,XT_Aux_On_Min,XT_Aux_Off_Min,XDT_Aux_On,XDT_Aux_Off]=ndgrid(DBuck_On,Mode_Control,DT_Comp_Mode,Fs,DT_On,DT_Off,T_On_Min,T_Off_Min,Aux_Control,T_Aux_On_Min,T_Aux_Off_Min,DT_Aux_On,DT_Aux_Off);
clear DBuck_On Mode_Control DT_Comp_Mode Fs DT_On DT_Off T_On_Min T_Off_Min Aux_Control T_Aux_On_Min T_Aux_Off_Min DT_Aux_On DT_Aux_Off
XDBuck_On = XDBuck_On(:);
XMode_Control=XMode_Control(:);
XDT_Comp_Mode=XDT_Comp_Mode(:);
XFs=XFs(:);
XDT_On = XDT_On(:);
XDT_Off =XDT_Off(:);
XT_On_Min = XT_On_Min(:);
XT_Off_Min = XT_Off_Min(:);
XAux_Control = XAux_Control(:);
XT_Aux_On_Min = XT_Aux_On_Min(:) ;
XT_Aux_Off_Min = XT_Aux_Off_Min(:) ;
XDT_Aux_On =XDT_Aux_On(:);
XDT_Aux_Off =XDT_Aux_Off(:);
Flag = true;
MyData = cell(1, length(XDT_Aux_Off));
RoiData = cell(1, length(XDT_Aux_Off));
parfor k = 1 : length(XDT_Aux_Off)
MyData{k} = {};
RoiData{k} = {};
Ts=1/XFs(k);
Mode_Control=XMode_Control(k);
DT_Comp_Mode=XDT_Comp_Mode(k);
DT_On = XDT_On(k);
DT_Off =XDT_Off(k);
T_On_Min = XT_On_Min(k);
T_Off_Min = XT_Off_Min(k);
Aux_Control = XAux_Control(k);
T_Aux_On_Min = XT_Aux_On_Min(k) ;
T_Aux_Off_Min = XT_Aux_Off_Min(k) ;
DT_Aux_On =XDT_Aux_On(k);
DT_Aux_Off =XDT_Aux_Off(k);
DBuck_Off = 1-XDBuck_On(k);
if (XMode_Control(k)==1)
DBuck_Off=0.5-XDBuck_On(k)/2;
end
D1=XDBuck_On(k);
D2=DBuck_Off;
D3=1-D1-D2;
sim('DPWMIgalSimulation_Comparison_RoiVersion_Vs_MyVersion');
MyRawData = csvread(strcat(pwd,'\MyTempTestVector.csv'));
RoiRawData = csvread(strcat(pwd,'\RoiTempTestVector.csv'));
if (~isequal(MyRawData,RoiRawData))
MyData{k}{end+1} = MyRawData;
RoiData{k}{end+1} = RoiRawData;
end
end
MyData = [MyData{:}];
RoiData = [RoiData{:}];
MyNewData=MyData(:,2:end);
RoiNewData=RoiData(:,2:end);
csvwrite(strcat(MyFileName,'_CCM','.csv'),MyNewData);
csvwrite(strcat(RoiFileName,'_CCM','.csv'),RoiNewData);
I used your proposal to change MyData/RoiData , and the parfor start to work and then output the following : * " Starting parallel pool (parpool) using the 'local' profile ... connected to 4 workers. Loaded PLECS module Version 3.7.5 Warning: dialog is no longer supported when MATLAB is started with the -nodisplay or -noFigureWindows option or there is no display. For more information, see "Changes to -nodisplay and -noFigureWindows Startup Options" in the MATLAB Release Notes. To view the release note in your system browser, run web('www.mathworks.com/help/matlab/release-notes.html#br5ktrh-3', '-browser') > In warnfiguredialog (line 21) Loaded PLECS module Version 3.7.5 Warning: dialog is no longer supported when MATLAB is started with the -nodisplay or -noFigureWindows option or there is no display. For more information, see "Changes to -nodisplay and -noFigureWindows Startup Options" in the MATLAB Release Notes. To view the release note in your system browser, run web('www.mathworks.com/help/matlab/release-notes.html#br5ktrh-3', '-browser') > In warnfiguredialog (line 21) In dialog (line 35) In msgbox (line 211) In errordlg (line 47) In parallel_function>make_general_channel/channel_general (line 914) In remoteParallelFunction (line 38) Error evaluating expression 'SimTime' for 'StopTime' specified in the Configuration Parameters dialog for block diagram 'DPWMIgalSimulation_Comparison_RoiVersion_Vs_MyVersion': Undefined function or variable 'SimTime'"*
but simtime is indeed defined (Its the simulation time in the slx file).
at the beginning he had an other error : * "Starting parallel pool (parpool) using the 'local' profile ... connected to 4 workers. File 'M:\Users\Omer_o\Matlab05_forOmer\DPWMIgalSimulation_Comparison_RoiVersion_Vs_MyVersion.slx' does not contain a valid Simulink model in SLX format: Could not open source package"*
short overview : The simulation has plecs blocks with 13 Block Parameters (DbuckOn, DTCom..) inside . Then when i define the parameters in workspace i can run the simulation. May the errors cause due to problems running the same simulation with different parameters in multithreaded way ? Any suggestions ?
** After a friend suggestion he said that the better if i pass all input parameters in the sim function itself so the workers could work in parallel mode , but every time i try to pass a input paramter with sim it has the error : _ *"Trial>> sim('DPWMIgalSimulation_Comparison_RoiVersion_Vs_MyVersion','Ts',1e-5) block_diagram does not have a parameter named 'Ts'
Trial>> get_param('DPWMIgalSimulation_Comparison_RoiVersion_Vs_MyVersion','Ts') block_diagram does not have a parameter named 'Ts'"*_
Maybe this could solve the problem , but i can figure why it doesnt recognize my block parameters.
Thanks a lot. Omer

Sign in to comment.


Titus Edelhofer
Titus Edelhofer on 17 Jun 2016
Hi Omer,
usually it's best to put the call to sim into a function. Pass the variables to the function as they are needed, something like
function y = simulate(k, Ts, Mode_Control, DT_Comp_Mode)
sim('DPWMIgalSimulation_Comparison_RoiVersion_Vs_MyVersion', 'SrcWorkspace', 'current');
end
Why k? You should make sure, that the filename includes the "k", otherwise parallel simulations would write into the same .csv file.
Read the csv files afterwards (i.e., after the call to "simulate") and delete them in order to not have hundreds of files.
Titus

  6 Comments

Show 3 older comments
omer
omer on 21 Jun 2016
Hey Titus, Now i tried to implement as follow :
MyData = cell(1, length(XDT_Aux_Off));
RoiData = cell(1, length(XDT_Aux_Off));
MyRawData=cell(1,length(XDT_Aux_Off));
RoiRawData=cell(1,length(XDT_Aux_Off));
SimOut=cell(1,length(XDT_Aux_Off));
spmd
load_system('DPWMIgalSimulation_Comparison_RoiVersion_Vs_MyVersionPar');
end
MyWorkSpace=find_system(gcs,'Name','To Workspace');
RoiWorkSpace=find_system(gcs,'Name','To Workspace1');
parfor k = 1 : length(XDT_Aux_Off)
MyData{k} = {};
RoiData{k} = {};
MyRawData{k}={};
RoiRawData{k}={};
SimOut{k}={};
set_param(MyWorkSpace{1},'VariableName',strcat('MyOut',num2str(k)));
set_param(RoiWorkSpace{1},'VariableName',strcat('RoiOut',num2str(k)));
SimOut{k}=simulate(k, XTs(k), XMode_Control(k), XDT_Comp_Mode(k),XDT_On(k),XDT_Off(k),XT_On_Min(k),XT_Off_Min(k),XAux_Control(k),XT_Aux_On_Min(k),XT_Aux_Off_Min(k),XDT_Aux_On(k),XDT_Aux_Off(k),XD1(k),XD2(k),XD3(k));
MyRawData{k}=SimOut{k}.get(strcat('MyOut',num2str(k)));
RoiRawData{k}=SimOut{k}.get(strcat('RoiOut',num2str(k)));
if (~isequal(MyRawData{k},RoiRawData{k}))
MyData{k}{end+1} = MyRawData{k}{end+1};
RoiData{k}{end+1} = RoiRawData{k}{end+1};
end
end
MyData = [MyData{:}];
RoiData = [RoiData{:}];
csvwrite(strcat(MyFileName,'_CCM','.csv'),MyData);
csvwrite(strcat(RoiFileName,'_CCM','.csv'),RoiData);
when simulate looks like this :
function y = simulate(k, mTs, mMode_Control, mDT_Comp_Mode,mDT_On,mDT_Off,mT_On_Min,mT_Off_Min,mAux_Control,mT_Aux_On_Min,mT_Aux_Off_Min,mDT_Aux_On,mDT_Aux_Off,mD1,mD2,mD3)
assignin('base','k',k);
assignin('base','Ts',mTs);
assignin('base','Mode_Control',mMode_Control);
assignin('base','DT_Comp_Mode',mDT_Comp_Mode);
assignin('base','DT_On',mDT_On);
assignin('base','DT_Off',mDT_Off);
assignin('base','T_On_Min',mT_On_Min);
assignin('base','T_Off_Min',mT_Off_Min);
assignin('base','Aux_Control',mAux_Control);
assignin('base','T_Aux_On_Min',mT_Aux_On_Min);
assignin('base','T_Aux_Off_Min',mT_Aux_Off_Min);
assignin('base','DT_Aux_On',mDT_Aux_On);
assignin('base','DT_Aux_Off',mDT_Aux_Off);
assignin('base','D1',mD1);
assignin('base','D2',mD2);
assignin('base','D3',mD3);
assignin('base','SampleTime',0);
y=sim('DPWMIgalSimulation_Comparison_RoiVersion_Vs_MyVersionPar', 'SrcWorkspace', 'current');
meaning now i save simout{k} which can be changed in parallel . then i use get in order to retreive the data.
but i get an error :
It says i have a block to file in my plecs blocks , but i deleted it and there is no such block there . I triple checked in my model to make sure. Any idea?
Titus Edelhofer
Titus Edelhofer on 21 Jun 2016
Hi Omer,
two comments: I guess the warning at the beginning is what you might have missed. Closing the parpool and opening it again might already help.
Second, why are you assigning the variables to base workspace? The parameter 'SrcWorkspace', 'Current' tells Simulink to use the variables from the current workspace anyway. No need to assign them all to base (only you need to be consistent in naming).
Titus
omer
omer on 21 Jun 2016
Hey Titus 1. I didnt understand this warning and its cause . what is the soultion to this warning? 2. Because it didnt work, see my previouse comment. when i assign the parameters as normal (Ts=XTs(k),...) it doesnt know them and produce a warning underline

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by