%% Control parfor Range Partitioning
% You can control how parfor divides iterations into subranges for the workers with parforOptions. Controlling the range partitioning can optimize performance of a parfor-loop. For best performance, try to split into subranges that are:
% Large enough that the computation time is large compared to the overhead of scheduling the subrange
% Small enough that there are enough subranges to keep all workers busy
% To partition iterations into subranges of fixed size, create a set of parfor options, set 'RangePartitionMethod' to 'fixed', and specify a subrange size with 'SubrangeSize'.

opts = parforOptions(parcluster,'RangePartitionMethod','fixed','SubrangeSize',2);

% Pass the parfor options as the second input argument to parfor. In this case, parfor divides iterations into three groups of 2 iterations.

values = [3 3 3 3 3 3];
parfor (i=1:numel(values),opts)
    out(i) = norm(pinv(rand(values(i)*1e3)));
end

% To partition iterations into subranges of varying size, pass a function handle to the 'RangePartitionMethod' name-value pair. This function must return a vector of subrange sizes, and their sum must be equal to the number of iterations. For more information on this syntax, see method.

opts = parforOptions(parcluster,'RangePartitionMethod', @(n,nw) [2 1 1 2]);

% Pass the parfor options as the second input argument to parfor. In this case, parfor divides iterations into four groups of 2, 1, 1, and 2 iterations.

values = [3 3 7 7 3 3];
parfor (i=1:numel(values),opts)
    out(i) = norm(pinv(rand(values(i)*1e3)));
end

% Copyright 2018 The MathWorks, Inc.