Parallel processing to update plot

26 views (last 30 days)
mindra
mindra on 13 Dec 2015
Edited: Emory Salberg on 24 Mar 2021
Hello all and thanks in advance for reading this question.
I need to run a simulation in a simulink loop. The loop involves that at each iteration a plot is updated according to the results. This makes the simulation to run to slow. I want to use parallel processing to update the plot according to the simulation results by using another core of my CPU. For this purpose, I have been playing around using the batch command and parfor command without much success.
I wonder if anybody can give me some hints on what is the best way to address this. It would be like a separate process that at each iteration reads some numerical values from the simulink loop, and updates the plot using another core. I guess the communication between processes could be achieved with some global variables. So basically it will be a separate script to update the plot according to these variables. And this script needs to run in such a way that it wont not slow down noticeably the simulink loop and vice-versa.
Thanks a lot, Mindra
  1 Comment
mindra
mindra on 13 Dec 2015
Just an additional comment: some of you may give me the advice of not refreshing the plot at each iteration to make things faster or to check on some simulink optimization tips for speed performance. I have already done that but the improvement was not enough.

Sign in to comment.

Accepted Answer

Edric Ellis
Edric Ellis on 14 Dec 2015
It's possible that you might be able to use parfeval to achieve this. You cannot use global variables for the communication, as pointed out by Walter. parfeval is very similar to batch, except that it uses workers from your parallel pool - and therefore the overheads of running stuff are typically much lower. For instance, you could keep the Simulink model open on the worker between runs.
Following on from Walter's suggestion, you need a function that calls sim. Then, on your MATLAB client, you call parfeval to invoke that function on a worker. The client then waits for completion of the work - perhaps using fetchNext, and then retrieves the results. The client must update the plot.
There's an example here in the doc of this sort of thing.
  7 Comments
Walter Roberson
Walter Roberson on 15 Dec 2015
Make the first parfeval call. Enter a loop of waiting for a result, copying off whatever info you will need to plot with, start another parfeval for the next iteration, then while it is executing update the plot with the results just recorded.
Unless your plot is very dense or takes a lot of calculation after the sim() call has returned, chances are that the overhead of using the parallel worker will exceed the amount of work needed for the plotting and that you will find this arrangement to be slower than if you had not done parallel work at all.
mindra
mindra on 15 Dec 2015
Yes I think you are right. I will have to find another approach or to use a faster computer for this task.
Thanks a lot to both of you for your time!

Sign in to comment.

More Answers (3)

Walter Roberson
Walter Roberson on 13 Dec 2015
You cannot use global variables to communicate between workers. Global variables are not transferred to the workers or back from the workers.
Workers cannot update the graphics display.
Batch... that might work.
  3 Comments
Walter Roberson
Walter Roberson on 13 Dec 2015
The batch processes would run sim() and return results (pulling them out of the function workspace and returning them if necessary.) The process that created the batch would be monitoring the returns and plotting the values as they become available.
I have not looked at this much, but I do know that it is possible to examine the returns before the entire batch is complete. It might take me a while to find appropriate documentation (I have not read much about batch.)
mindra
mindra on 14 Dec 2015
Thank you very much Walter.

Sign in to comment.


kendur
kendur on 5 Jun 2018
I think one possible solution you can apply is that you use two processes: First one takes data and save into files with names followed by order numbers such as "name_00.dat, name_01.dat, ..." after every data block transferred, the other one checks if the order number is updated by finding the file name and refresh the plot.

Emory Salberg
Emory Salberg on 24 Mar 2021
Edited: Emory Salberg on 24 Mar 2021
Workaround for passing variables. Look up "matlab memory mapping". Works well for communicating between applications. May help you too.
I was struggling for a while on a similar problem and this was the best solution. Only takes ~1ms to grab data.
%%%%%%%%%%
disp("IN PID2...");
tempv(1,3:5) = [R2_phidot_error(pidIdx2,3:5)];
out_msg = sprintf("%.1f," , tempv(1,:));
out_msg = strip(out_msg,'right',','); % strip final comma
out_msg = strcat("<"+out_msg,">");
disp('PID2_out: '+out_msg);
fileID = fopen('fromMatlab2.txt','w');
fwrite(fileID, out_msg,'char');
fclose(fileID);
disp("EXIT PID2...");
%%%%%%%%%%%%%
function msgReceived2(msg)
try
global readIdx2 finishR2 sOfVector
global R2_SumT R2_ENC R2_E1 R2_E2 R2_E3 R2_Q3 R2_Q4 R2_Q5 R2_FM
global Mymsg
msgin = msg;
Mymsg = msgin;
msgin2 = char(extractBetween(msgin,"<",">"));
msginCell = str2double(strsplit(msgin2,','));
R2_SumT(readIdx2) = msginCell(1);
R2_E1(readIdx2) = msginCell(2);
R2_E2(readIdx2) = msginCell(3);
R2_E3(readIdx2) = msginCell(4);
R2_ENC(readIdx2,1:3) = [R2_E1(readIdx2),R2_E2(readIdx2),R2_E3(readIdx2)];
R2_Q3(readIdx2) = msginCell(5);
R2_Q4(readIdx2) = msginCell(6);
R2_Q5(readIdx2) = msginCell(7);
R2_FM(readIdx2) = msginCell(8);
if(readIdx2>=sOfVector)
finishR2 = 1;
end
readIdx2 = readIdx2 + 1;
catch
wut = 0;
end
end
  1 Comment
Emory Salberg
Emory Salberg on 24 Mar 2021
You will be essentially writing a vecotor with known delimiters to a .txt file and then reading in values from another file. The file is never 'opened' so it saves a lot of time as you are directly reading/writing from the memory.
Also, forgot to enclude how to read the files. Its usuful to keep all of your files within the same workspace as well. Note, i was passing data to and from a python terminal running in Visual Studious, hence the 'fromPython2.txt'.
msgin=textread('fromPython2.txt','%s');
Best,

Sign in to comment.

Categories

Find more on Interactive Control and Callbacks in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!