Is it possible make parallel processing using MEX and OpenMP on Matlab?

6 views (last 30 days)
Hello. I am making the neural recording and processing program with Matlab. the whole process are receiving from acquisition board - Data processing - Plot updating However, the process time for updating plot is too long and it dose not use all process(threads), so I want to run parallel processing of data processing and plot updating.
my plan is that make mex code which update plots using Matlab functions(plot or set) or other C library and add OpenMP code to run on parallel. by this, Matlab main thread simultaneously run both data processing code and several threads update plots.
is it possible? before starting, please check my thinking is possible!
and i add my code. please review that and give me some advices
thanks!
% I make 4 plot objects having 8 subplots.
% timeStamps and Amplifiers have 10080 samples.
for i = 1:32
subPlot(i) = subplot(8,4,i);
if 1 <= i && i <= 8
DataRawLine1(i) = plot(subPlot(i), timeStamps, Amplifiers(1,:));
elseif 9 <= i && i <= 16
DataRawLine2(i-8) = plot(subPlot(i), timeStamps, Amplifiers(1,:));
elseif 17 <= i && i <= 24
DataRawLine3(i-16) = plot(subPlot(i), timeStamps, Amplifiers(1,:));
elseif 25 <= i && i <= 32
DataRawLine4(i-24) = plot(subPlot(i), timeStamps, Amplifiers(1,:));
end
subPlot(i).XLim = [0 10080/20000];
subPlot(i).YLim = [-500 500];
subPlot(i).XTick = [];
subPlot(i).YTick = [];
end
% This code read data from FPGA USB interface board (data acquisition board)
% datablock.Amplifiers have 60 samples. for 12 times, newdata gets 720 samples.
for i = 1:12
datablock.read_next(board);
save_index = (i-1)*60 + 1;
newdata(indexChannels,save_index:save_index + 59) = datablock.Chips{1,1}.Amplifiers(indexChannels,:) * 1000000; % change unit V to uV
end
% this code update plots. we have too many plots, so updating whole plots every time spend
% too much time (we have only 36ms for each cycle, read, process and update). we divide 4
% plot objects and update each objects (8 subplots) in every cycle.
if refresh == 0
set(DataRawLine1, {'Ydata'}, num2cell(Amplifiers(1:8,:),2));
pause(0.000001); % wait until plots are updated
elseif refresh == 1
set(DataRawLine2, {'Ydata'}, num2cell(Amplifiers(9:16,:),2));
pause(0.000001); % wait until plots are updated
elseif refresh == 2
set(DataRawLine3, {'Ydata'}, num2cell(Amplifiers(17:24,:),2));
pause(0.000001); % wait until plots are updated
elseif refresh == 3
set(DataRawLine4, {'Ydata'}, num2cell(Amplifiers(25:32,:),2));
pause(0.000001); % wait until plots are updated
end
refresh = refresh + 1;
if refresh == 4
refresh = 0;
end
  4 Comments

Sign in to comment.

Accepted Answer

James Tursa
James Tursa on 24 Oct 2017
Edited: James Tursa on 24 Oct 2017
For what you are attempting, probably not. Calling MATLAB API functions that allocate/deallocate memory in mex routines is generally not thread safe. Since updating plots will in all likelihood involve memory allocation/deallocation, updating multiple plots in parallel from a mex routine will likely not be thread safe and may bomb MATLAB. You would probably have better luck if you could move all of the MATLAB memory stuff outside the parallel section and just do other known thread safe stuff inside the parallel section.
  4 Comments
Walter Roberson
Walter Roberson on 27 Oct 2017
MATLAB variables are not just malloc()'d as needed. MATLAB variables have headers that indicate data type and sizes and usage counts and where the actual data is stored. MATLAB routines need to be passed the address of one of these data structures, not just the address of the data.
If you were to malloc() some memory for data and were to put that inside the kind of header needed by MATLAB, then MATLAB would assume that the actual memory was allocated out of the pools it is keeping, and would try to return the memory to those pools when it was finished with the call. That would get confusing because it never allocated that memory.
So, if you want MATLAB to be able to deal with data, you have to ask MATLAB for room to store the data. Unfortunately that asking is not thread safe: if two threads ask at the same time, or if one thread is freeing data while another is requesting data, then MATLAB's data pools can get corrupted.

Sign in to comment.

More Answers (1)

Jan
Jan on 24 Oct 2017
Is newdata pre-allocated?
newdata = zeros(max(indexChannels, 720)); % A guess, adjust to the available info
for i = 1:12
datablock.read_next(board);
save_index = (i-1)*60 + 1;
newdata(indexChannels,save_index:save_index + 59) = ...
datablock.Chips{1,1}.Amplifiers(indexChannels,:) * 1000000;
end
Try to replace pause(0.000001) by drawnow with the "limitrate", "nocallbacks" or "update" flags.
I assume that set(DataRawLine1, {'Ydata'}, num2cell(... has the same speed as a loop:
for k = 1:8
set(DataRawLine1(k), 'YData', Amplifiers(k,:));
end
But in general your screen output looks efficient already.
In theory distributing the work over 2 threads seems to be useful: One for the data acquisition, one for the display. But the communication between the parts is not easy. The part for displaying should not use a partially filled data buffer. While it is easy to let a thread run in the background, while the main routine of a MEX returns to Matlab, it is not trivial to obtain the data from this thread efficiently in real-time.
  1 Comment
sungwon min
sungwon min on 25 Oct 2017
Edited: sungwon min on 25 Oct 2017
Thanks your comment, and also thanks to answer my ex-questions which i posted before. yes the new data are pre-allocated. I have one more question! how can i easily run another thread in background? i think use Mex code with OpenMP libray, but that is too complicated. can you advice me?

Sign in to comment.

Categories

Find more on MATLAB 시작하기 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!