MATLAB Answers

Implement Parfor loop with nested for loops with multiple variables and some switch-case loops

12 views (last 30 days)
Federica Mauri
Federica Mauri on 16 Jan 2017
Edited: Stephen on 19 Jan 2017
Good morning, I'm in toruble with my script (you can find it below). I've 30 for-loops, which have 5 switch-case loops in. Unfortunately, I need 4 vectors as input for my function "pregusci". I know that it's so slow, so I need to speed it up with parallel computing, i.e. parfor loops (I found some examples with parfor and ind2sub), but I don't know how to do that.
Thank you for your attention,
Federica
clear, clc, close all
baia = [22400/(23+11*2) 22400/(23+11*4)];
S = [];
SPAZ1 = [30:5:70];
SPAZ2 = [30:5:70];
for i = 1:length(SPAZ1)
for j = 1:length(SPAZ2)
SPAZ3 = 100 - SPAZ1(i) - SPAZ2(j);
if SPAZ3 >= 10 && SPAZ3 <= 90
s = [SPAZ1(i) SPAZ2(j) SPAZ3];
S = [S; s];
end
end
end
D = 1;
mat = [2024 7075];
t = [2:0.1:5];
for p = 1:length(baia)
for i1 = 1:5
switch i1
case 1
j = [1:32];
case 2
j = [15:66];
case 3
j = [5:7];
case 4
j = [1:8];
case 5
j = [1:22];
end
%
for j1 = j(1):j(end)
for i2 = 1:5
switch i2
case 1
j = [1:32];
case 2
j = [15:66];
case 3
j = [5:7];
case 4
j = [1:8];
case 5
j = [1:22];
end
%
for j2 = j(1):j(end)
for i3 = 1:5
switch i3
case 1
j = [1:32];
case 2
j = [15:66];
case 3
j = [5:7];
case 4
j = [1:8];
case 5
j = [1:22];
end
%
for j3 = j(1):j(end)
for i4 = 1:5
switch i4
case 1
j = [1:32];
case 2
j = [15:66];
case 3
j = [5:7];
case 4
j = [1:8];
case 5
j = [1:22];
end
%
for j4 = j(1):j(end)
for i5 = 1:5
switch i5
case 1
j = [1:32];
case 2
j = [15:66];
case 3
j = [5:7];
case 4
j = [1:8];
case 5
j = [1:22];
end
%
for j5 = j(1):j(end)
tipo = [i1 i2 i3 i4 i5];
sez = [j1 j2 j3 j4 j5];
for n_CD = N*2:15
for n_CV = N*2:15
for k = 1:size(S,1)
s = S(k,:);
for k1 = 1:2
MAT(1) = mat(k1);
for k2 = 1:2
MAT(2) = mat(k2);
for k3 = 1:2
MAT(3) = mat(k3);
for k4 = 1:2
MAT(4) = mat(k4);
for k5 = 1:2
MAT(5) = mat(k5);
for k6 = 1:2
MAT(6) = mat(k6);
for k7 = 1:2
MAT(7) = mat(k7);
for l1 = 1:length(t)
T(1) = t(l1);
for l2 = 1:length(t)
T(2) = t(l2);
for l3 = 1:length(t)
T(3) = t(l3);
for l4 = 1:length(t)
T(4) = t(l4);
for l5 = 1:length(t)
T(5)= t(l5);
try
[filename,n_corr,n_pann]=pregusci(opzione,tipo ,sez,s,MAT,T,n_CD,n_CV,baia(p),N,profilo,carichi,output,fattsic);
[fidshortprt]=gusci(filename);
[D]=read_shortprt(fidshortprt,n_corr,n_pann,D,filename);
close all
fclose('all');
catch
close all
fclose('all');
end
clc
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end
end

Answers (1)

Vandana Ravichandran
Vandana Ravichandran on 19 Jan 2017
Edited: Vandana Ravichandran on 19 Jan 2017
When "parfor" is used instead of "for" loop, several MATLAB workers are concurrently computing the different iterations of the loop, so a parfor-loop can provide significantly better performance than its analogous for-loop. The total number of iterations are divided among the parallel MATLAB workers. Each iteration is independent and the execution of these iterations by different workers is not synchronized
It's important to decide when to use parfor loop: a. There should not be any loop dependency, meaning your loop should not have statements that depend on results from a previous (or a different) iteration. b. There is a communication overhead as we are using multiple workers in parfor. If the computation in your loop is relatively simple or small in size, there may be little advantage when compared to the scenario where there is significant computation.
In your example:
for i = 1:length(SPAZ1)
for j = 1:length(SPAZ2)
SPAZ3 = 100 - SPAZ1(i) - SPAZ2(j);
if SPAZ3 >= 10 && SPAZ3 <= 90
s = [SPAZ1(i) SPAZ2(j) SPAZ3];
S = [S; s];
end
end
end
A for loop can be parallelized by replacing "for" keyword with "parfor". If there are nested for loops, generally, the outermost for-loop is converted to parfor. Since there is no loop dependency, in this example, we can use parfor in the following way:
parfor i = 1:length(SPAZ1)
for j = 1:length(SPAZ2)
SPAZ3 = 100 - SPAZ1(i) - SPAZ2(j);
if SPAZ3 >= 10 && SPAZ3 <= 90
s = [SPAZ1(i) SPAZ2(j) SPAZ3];
S = [S; s];
end
end
end
Here, the outer for loop (running from 1 to length(SPAZ1)) is divided among the workers and the nested for loop inside parfor is executed by individual workers independent of each other.
The documentation has a good example which is related to your question: https://www.mathworks.com/help/distcomp/convert-nested-for-loops-to-parfor.html
Note that you need to have the parallel computing toolbox to use this feature.

Community Treasure Hunt

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

Start Hunting!

Translated by