0
votes

I need help to know how to work with variables defined outside parfor loops. I want to speed up a code that takes to much time when using higher number of elements.

I will try to explain it with an example. Let's suppose that initially I have a series of elements that will move randomly inside a loop and some calculations will take place according to the position of the elements.

Here is an example of the code:

% Variables
nElements = 5000; Ly = 2; vmax = 1;
time = 0.1:0.1:20;
x = -0.5+rand(nElements,1);
y = -Ly + Ly*rand(nElements,1);
zx = [];
zy = [];
rate = zeros(1,length(time));
vel = zeros(nElements,1);
vz = [];

% Loop
parfor ii=1:length(time)
nTimes = ii;                   % counter
vel = vmax.*(1-(y./Ly).^2)     % elements will move according to this velocity profile
x = x + vel + randn(nElements,1);
y = y + vel + randn(nElements,1);

nZ = length(zx);
if ~isempty(zx) && ~isempty(zy)
   vz = vmax.*(1-(zy./Ly).^2)
   zx = zx + vz + randn(nZ,1);
   zy = zy + vz + randn(nZ,1);
end


[x,y,zx,zy] = f(x,y,zx,zy); % function that uses the variables x and y; and if some conditions are met, creates a z element   
rate(ii) = nZ;
end

I'm having problems with variables that are set outside the parfor loop and also due to the way variables are used. What I would like to know is how to use variables (that are defined outside) inside the parfor loop and how to work with them in functions if the variables are updated in every loop.

Thanks!

1
I don't see how this could ever be parallelized. At each time step, the value of y is dependent on the previous value of y. - drhagen
Thanks for the answer @drhagen. Exactly! It seems that my code is dependent. What I would like to know is how to overcome this kind of problems, are there any tricks? For example in this code (similar to the problem I'm dealing with): a = zeros(1,10); parfor it = 1:10 a(it) = someFunction(a(it-1)); end It is clear that each iteration is dependent. But how can I modify this to run succesfully the code? - S. Perez
Turn the parfor into a regular for? - drhagen
Yes, that's what I had before I tried to convert it to parfor :). Anyway, thanks for the answer! - S. Perez

1 Answers

1
votes

Parallelizing over time (or any system where the value at each step depends on the previous value) is impossible, not just in Matlab, but fundamentally.

Fortunately, Matlab will use built-in multithreading for much of the code shown here because your code can be vectorized along the nElements dimension. Vectorized operations are already parallelized internally. The slow part of this particular code is randn, a function which is both computationally expensive and typically sequential. If I remove that and look at the processor usage, I see multiple cores being used:

% Variables
nElements = 1000000; Ly = 2; vmax = 1;
time = linspace(0,1,100000);
x = -0.5+rand(nElements,1);
y = -Ly + Ly*rand(nElements,1);
vel = zeros(nElements,1);

% Loop
for ii=1:length(time)
    vel = vmax.*(1-(y./Ly).^2);
    x = x + vel;
    y = y + vel;
end