# Choosing which nested for loop to parfor

2 views (last 30 days)
elvin feng on 28 Jun 2017
Commented: Jan on 28 Jun 2017
I am trying to read in images that contains varying parameters (series, time, channels, zslices) and have a few nested for loops to go through it all. When trying to parallelize it, sometimes it might be more efficient to stick the parfor on the parameter that has more values. Is there a way to decide which for loop to parfor if I have the variables nSeries, nTime, etc. in a way that doesn't involve rewriting the code with different possible functions?
Thanks.
Trial and error is often the best way, though remember that there is an overhead to copying data to the workers so you want to parallelise at the point where you will do maximum work on each worker before having to copy data back again.

Jan on 28 Jun 2017
Edited: Jan on 28 Jun 2017
Perhaps I misunderstand your question. A guess:
As far as I understand, you have:
for i1 = 1:N1
for i2 = 1:N2
perform_th_job(i1, i2);
end
end
And now you know, e.g. by a measurement, that for some N1, N2 this is faster:
parfor i1 = 1:N1
for i2 = 1:N2
and for others N1, N2 it is
for i1 = 1:N1
parfor i2 = 1:N2
Now you want to shwitch dynamically between both methods and not to write two versions of the code.
If all computations are moved to a dedicated function as in my example, creating both methods would easy and tight:
if N1 > N2
parfor i1 = 1:N1
for i2 = 1:N2
perform_th_job(i1, i2);
end
end
else
for i1 = 1:N1
parfor i2 = 1:N2
perform_th_job(i1, i2);
...
But Matlab's JIT accelerator migt be impeded by this and the for loop might run slower.
Therefore I suggest an evil method: Create a Matlab pre-processor.
function myFunction(N1, N2)
for i1 = 1:N1 %@ PARFOR1
for i2 = 1:N2 %@ PARFOR2
... all the code you need
end
end
Edit, maintain and debug this file only. Create the two versions automatically:
C = splitstr(S, '\n');
match = contains(C, '%@ PARFOR1');
C(match) = strrep(C(match), 'for', 'parfor');
fid = fopen('myFunction_PARFOR1.m', 'w');
fprintf(fid, '%s\n', C{:});
end
The same for PARFOR2. Now the main function looks like:
if doDebug
myFunction(N1, N2);
elseif N1 > N2
myFunction_PARFOR1(N1, N2);
else
myFunction_PARFOR2(N1, N2);
end
Now you have the advantage of having 1 file only for the maintenance, but two different functions for running with optimal speed.
This has the disadvanatge, that you have to remember to create the two functions after each update of the original function. Thuis sounds trivial, but such a software management is as hard as a backup: If in doubt, it has been forgotton.
I admit, I have a bunch of such pre-processor functions. I can switch flags to adjust my code for Windows and Linux, change strings according to the language of the user, enable/disable lines and blocks of code depeneding on the lab the software is working in, insert the date of the release, such that the output to the command window contains the version number of the toolbox. This can also activate workarounds for specific Matlab versions.
This is very useful, but it must be handled with care to avoid unreadable code or bugs, which are hard to find, because the code is changed dynamically. You should avoid under all circumstances to modify the code dynamically during the program runs, because this would cause the same troubles as eval.
By the way: eval does not work - and even if it does, I would recommend to avoid it.
eval('parfor i = 1:10') % FAILS WITH ERROR
disp(i)
eval('end')
eval('parfor i = 1:10; disp(i), end') % WORKS, BUT IS SLOW AND EVIL
##### 2 CommentsShowHide 1 older comment
Jan on 28 Jun 2017
Use it carefully. Create backups. Insert a time stamp and a "DO NOT EDIT THIS FILE, BUT [original file name]" in the automatically modified files. Document all changes exhaustively, such that the process is clear for your successor in 8 years. Let this be an exception. If you have 20 of such automagically edited files and they are nested, the confusion will be perfect.
Good luck :-)