## # Using parfor to parallelize a loop

You can use `parfor` to execute the iterations of a loop in parallel:

Example:

``````poolobj = parpool(2);       % Open a parallel pool with 2 workers

s = 0;                      % Performing some parallel Computations
parfor i=0:9
s = s + 1;
end
disp(s)                     % Outputs '10'

delete(poolobj);            % Close the parallel pool

``````

Note: `parfor` cannot be nested directly. For `parfor` nesting use a function in fisrt `parfor` and add second `parfor` in that function.

Example:

``````parfor i = 1:n
[op] = fun_name(ip);
end

function [op] = fun_name(ip)
parfor j = 1:length(ip)
% Some Computation
end

``````

## # When to use parfor

Basically, `parfor` is recommended in two cases: lots of iterations in your loop (i.e., like `1e10`), or if each iteration takes a very long time (e.g., `eig(magic(1e4))`). In the second case you might want to consider using `spmd` . The reason `parfor` is slower than a `for` loop for short ranges or fast iterations is the overhead needed to manage all workers correctly, as opposed to just doing the calculation.

Also a lot of functions have implicit multi-threading built-in, making a `parfor` loop not more efficient, when using these functions, than a serial `for` loop, since all cores are already being used. `parfor` will actually be a detriment in this case, since it has the allocation overhead, whilst being as parallel as the function you are trying to use.

Consider the following example to see the behaviour of `for` as opposed to that of `parfor`. First open the parallel pool if you've not already done so:

``````gcp; % Opens a parallel pool using your current settings

``````

Then execute a couple of large loops:

``````n = 1000; % Iteration number
EigenValues = cell(n,1); % Prepare to store the data
Time = zeros(n,1);
for ii = 1:n
tic
EigenValues{ii,1} = eig(magic(1e3)); % Might want to lower the magic if it takes too long
Time(ii,1) = toc; % Collect time after each iteration
end

figure; % Create a plot of results
plot(1:n,t)
title 'Time per iteration'
ylabel 'Time [s]'
xlabel 'Iteration number[-]';

``````

Then do the same with `parfor` instead of `for`. You will notice that the average time per iteration goes up. Do realise however that the `parfor` used all available workers, thus the total time (`sum(Time)`) has to be divided by the number of cores in your computer.

So, whilst the time to do each separate iteration goes up using `parfor` with respect to using `for`, the total time goes down considerably.

## # Executing commands in parallel using a "Single Program, Multiple Data" (SPMD) statement

Unlike a parallel for-loop (`parfor`), which takes the iterations of a loop and distributes them among multiple threads, a single program, multiple data (`spmd`) statement takes a series of commands and distributes them to all the threads, so that each thread performs the command and stores the results. Consider this:

``````poolobj = parpool(2);    % open a parallel pool with two workers

spmd
q = rand(3);         % each thread generates a unique 3x3 array of random numbers
end

q{1}             % q is called like a cell vector
q{2}             % the values stored in each thread may be accessed by their index

delete(poolobj)  % if the pool is closed, then the data in q will no longer be accessible

``````

It is important to note that each thread may be accessed during the `spmd` block by its thread index (also called lab index, or `labindex`):

``````poolobj = parpool(2);        % open a parallel pool with two workers

spmd
q = rand(labindex + 1);  % each thread generates a unique array of random numbers
end

size(q{1})                   % the size of q{1} is 2x2
size(q{2})                   % the size of q{2} is 3x3

delete(poolobj)              % q is no longer accessible

``````

In both examples, `q` is a composite object, which may be initialized with the command `q = Composite()`. It is important to note that composite objects are only accessible while the pool is running.

## # Using the batch command to do various computations in parallel

To use multi-threading in MATLAB one can use the `batch` command. Note that you must have the Parallel Computing toolbox installed.

For a time-consuming script, for example,

``````for ii=1:1e8
A(ii)=sin(ii*2*pi/1e8);
end

``````

to run it in batch mode one would use the following:

``````job=batch("da")

``````

which is enables MATLAB to run in batch mode and makes it possible to use MATLAB in the meantime to do other things, such as add more batch processes.

To retrieve the results after finishing the job and load the array `A` into the workspace:

``````load(job, 'A')

``````

Finally, open the "monitor job gui" from HomeEnvironmentParallelMonitor jobs and delete the job through:

``````delete(job)

``````

To load a function for batch processing, simply use this statement where `fcn` is the function name, `N` is number of output arrays and `x1`, `...`, `xn` are input arrays:

``````
j=batch(fcn, N, {x1, x2, ..., xn})

``````