problem with parfor and struct

Hey guys,
i have some problems with my parfor-loop. To explain my programm, i have written down an less complex version of my programm, wich is shown below.
I have two structures with some fields in it, wich i need for calcutations. So the idear is to calculate, struct1(1) with strucht2(1 to n), strucht1(2) with struct2(1 to n), ..., struct(m) with struct2(1 to n). My problem is, that the programm is slower with parfor then with for. I found out, that the problem is the line with "output(:, k) = output_z; ", but i dont know how to solve it different, because otherwise i dont get the output out of the parfor-loop.
If you have an idear what i could do, even if it something totaly different, im happy for your aswer.
Kind regards,
Daniel
struct1(200)=struct();
for k = 1:200
struct1(k).constant.A = round(5 + rand(1)*10);
struct1(k).constant.B = round(2 + rand(1)*10);
end
struct2(500)=struct();
for a = 1 : 500
struct2(a).d = 1+rand(1);
end
tic
parfor k = 1 : 200
[output_z] = loop(struct1(k), struct2)
output(:, k) = output_z;
end
toc
function [output] = loop(struct1, struct2)
for a = 1 : 500
[output(a)] = calculation(struct1, struct2(a));
end
end
function [struct1] = calculation(struct1, struct2)
struct1.pv = struct1.constant.A + struct1.constant.B * struct2.d;
end

9 comentarios

Do not grow variables dynamically. Pre-allocate output. Even if what it takes is
a = 1;
output(a) = calculation(struct1, struct2(a));
output(500).pv = []; %extends output to full size
for a = 2 : 500
output(a) = calculation(struct1, struct2(a));
end
In the case where the iterations are unrelated, as appears to be the case here, you can take the shortcut of instead programming
for a = 500 : -1 : 1
output(a) = calculation(struct1, struct2(a));
end
this creates the last entry and moves towards the first, and therefore never needs to make the array longer.
Daniel Ermer
Daniel Ermer el 6 de Mayo de 2019
Thank you for the aswer. I included your tip, but my ould problem remains.
If your problem is this trivially parallelizable and it is imperative that you get a significant speedup to get the job done perhaps you can parallelize it at the matlab-process-level with standard loops? It is an ugly suggestion - but if no calculation depends on the other results it ought to be possible to run batches of matlab-sessions starting different processing-runs with the -r trick:
> matlab -nodesktop -r process_0to50
> matlab -nodesktop -r process_51to100
...and so on. It is not pretty, but might get the job done, if doing it that way I'd start the processes in screen-sessions so that I can hide them from sight too...
Daniel Ermer
Daniel Ermer el 7 de Mayo de 2019
Thanks for the answer.
I think your Idear could work, but its not what im looking for. Im programming the groundwork and in the future people will ceep growing this programm, so i dont want some "tricky" solutions.
Matt J
Matt J el 7 de Mayo de 2019
What sort of parallel resources are you running this on? Not a cluster, I am guessing.
Bjorn Gustavsson
Bjorn Gustavsson el 7 de Mayo de 2019
@Daniel Ermer: I figured that it would be an "unsuitable" solution.
Do you absolutely need the structs? Can you re-organize your code using more basic (matrices...) data-types? If that wouldn't comlpetely kill the code-structure maybe you give parfor an easier time to figure out what memory is and is not affected by the calculations? <speculation>Once uppon a time when structs were new I managed to write a functions using structs with .next and .prev "pointing" to similar structs as if they were c-style pointers - even though that might not have been the case. I don't know if a struct-field pointing to another struct would now behave as a pointer, but if it did it would be possible to redirect it from its initial value in a function. If parfor is programmed to be cautious to such events then that might be why you get your problems...<\speculation>
Daniel Ermer
Daniel Ermer el 7 de Mayo de 2019
I have installed the "Parallel Computing Toolbox" and using an processor with four cores.
Walter Roberson
Walter Roberson el 7 de Mayo de 2019
It is quite common for parallel programs to be slower than serial.
  • overhead of sending data back and forth, especially if it decides that a variable has to be a broadcast variable instead of sliced
  • Parallel programs by default only get one thread per worker. If the work being done happens to be match one of the patterns common in linear algebra type operations (including just adding two matrices), then for large enough matrices, MATLAB normally calls one of the high performance multithreaded libraries. With workers only getting one thread, those end up being done in serial, with the difference being that several of those might be happening at the same time. It is common that you end up getting higher performance leaving the routines non-parallel
  • parallel typically wins for cases where not much memory needs to be shared and where the operations are quite independent and where the operations do not paralellize well. That happens often enough to be useful, but parfor taking 1.5 to 5 times longer is pretty common.
Thanks to you guys for all the answers. @Walter Roberson, now im going for an matrix as an output. It speeds even my simple version from 4 s (parfor), 1,5 s (for) to 0,6 s. I will have to tipe some more rows of code, but it works.
clear all
struct1(200)=struct();
for k = 1:200
struct1(k).constant.A = round(5 + rand(1)*10);
struct1(k).constant.B = round(2 + rand(1)*10);
end
struct2(500)=struct();
for a = 1 : 500
struct2(a).d = 1+rand(1);
end
tic
parfor k = 1 : 200
[out(k,:)] = loop(struct1(k), struct2);
end
for a = 1 : 1 : 200
evaluation(1+200*(a-1):200*a, :) = out(:,1+3*(a-1):3+3*(a-1));
end
toc
function [out] = loop(struct1, struct2)
for a = 500 : -1 : 1
[struct1] = calculation(struct1, struct2(a));
b = 3;
out(1,1+b*(a-1)) = struct1.pv;
out(1,2+b*(a-1)) = struct1.constant.A;
out(1,3+b*(a-1)) = struct1.constant.B;
end
end
function [struct1] = calculation(struct1, struct2)
struct1.pv = struct1.constant.A + struct1.constant.B * struct2.d;
end

Iniciar sesión para comentar.

Respuestas (0)

Categorías

Más información sobre Loops and Conditional Statements en Centro de ayuda y File Exchange.

Preguntada:

el 6 de Mayo de 2019

Abierta de nuevo:

el 13 de Mayo de 2019

Community Treasure Hunt

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

Start Hunting!

Translated by