Parallel processing in MATLAB
1 Overview
MATLAB provides a variety of functionality for parallelization, including threaded operations (linear algebra and more), parallel for loops, and parallelization across multiple machines. This material will just scratch the surface of what is possible.
2 Threading
Many MATLAB functions are automatically threaded (not just linear algebra), so you don’t need to do anything special in your code to take advantage of this. So if you’re running MATLAB and monitoring CPU usage (e.g., using top on Linux or OS X), you may see a process using more than 100% of CPU.
However worker tasks within a parfor use only a single thread.
MATLAB uses MKL for (threaded) linear algebra.
Threading in MATLAB can be controlled in two ways. From within your MATLAB code you can set the number of threads, e.g., to four in this case:
maxNumCompThreads(4);
To use only a single thread, you can use 1 instead of 4 above, or you can start MATLAB with the singleCompThread flag:
matlab -singleCompThread ...
3 Parallel for loops on one machine
To run a loop in parallel in MATLAB, you can use the parfor construction. Before running the parfor you need to start up a set of workers using parpool. MATLAB will use only one thread per worker. Here is some demo code:
nslots = 4; % to set manually
mypool = parpool(nslots)
n = 3000;
nIts = 500;
c = zeros(n, nIts);
parfor i = 1:nIts
c(:,i) = eig(rand(n));
end
delete(mypool)
% delete(gcp) works if you forget to name your pool by assigning the output of parpool to a variable
MATLAB has a default limit on the number of workers in a pool, but you can modify your MATLAB settings as follows to increase that limit (in this case to allow up to 32 workers). It should work to run the following code once in a MATLAB session, which will modify the settings for future MATLAB sessions.
cl = parcluster();
cl.NumWorkers = 32;
saveProfile(cl);
By default MATLAB uses a single thread (core) per worker. However you can also use multiple threads. Here is how you can set that up.
cl = parcluster();
cl.NumThreads = 2; % 2 threads per worker
cl.parpool(4); % 4 workers
4 Parallel random number generation
MATLAB also uses the Mersenne-Twister. We can set the seed as: rng(seed)
,
with seed being a non-negative integer.
Happily, like in R, we can set up independent streams, using either of
the Combined Multiple Recursive (‘mrg32k3a’) and the Multiplicative
Lagged Fibonacci (‘mlfg6331_64’) generators. Here’s an example, where
we create the second of the 5 streams, as if we were using this code
in the second of our parallel processes. The 'Seed',0
part
is not actually needed as that is the default.
thisStream = 2;
totalNumStreams = 5;
seed = 0;
cmrg1 = RandStream.create('mrg32k3a', 'NumStreams', totalNumStreams,
'StreamIndices', thisStream, 'Seed', seed);
RandStream.setGlobalStream(cmrg1);
randn(5, 1)
5 Manually parallelizing individual tasks
In addition to using parfor in MATLAB, you can also explicitly program parallelization, managing the individual parallelized tasks. Here is some template code for doing this. We’ll submit our jobs to a pool of workers so that we have control over how many jobs are running at once. Note that here I submit 6 jobs that call the same function, but the different jobs could call different functions and have varying inputs and outputs. MATLAB will run as many jobs as available workers in the pool and will queue the remainder, starting them as workers in the pool become available. Here is some demo code
feature('numThreads', 1);
ncores = 4;
pool = parpool(ncores);
% assume you have test.m with a function, test, taking two inputs
% (n and seed) and returning 1 output
n = 10000000;
job = cell(1,6);
job{1} = parfeval(pool, @test, 1, n, 1);
job{2} = parfeval(pool, @test, 1, n, 2);
job{3} = parfeval(pool, @test, 1, n, 3);
job{4} = parfeval(pool, @test, 1, n, 4);
job{5} = parfeval(pool, @test, 1, n, 5);
job{6} = parfeval(pool, @test, 1, n, 6);
% wait for outputs, in order
output = cell(1, 6);
for idx = 1:6
output{idx} = fetchOutputs(job{idx});
end
% alternative way to loop over jobs:
for idx = 1:6
jobs(idx) = parfeval(pool, @test, 1, n, idx);
end
% wait for outputs as they finish
output = cell(1, 6);
for idx = 1:6
[completedIdx, value] = fetchNext(jobs);
output{completedIdx} = value;
end
delete(pool);
And if you want to run threaded code in a given job, you can do that by setting the number of threads within the function called by parfeval. See the testThread.m file for the testThread function.
ncores = 8;
n = 5000;
nJobs = 4;
pool = parpool(nJobs);
% pass number of threads as number of slots divided by number of jobs
% testThread function should then do:
% feature('numThreads', nThreads);
% where nThreads is the name of the relevant argument to testThread
jobt1 = parfeval(pool, @testThread, 1, n, 1, nCores/nJobs);
jobt2 = parfeval(pool, @testThread, 1, n, 2, nCores/nJobs);
jobt3 = parfeval(pool, @testThread, 1, n, 3, nCores/nJobs);
jobt4 = parfeval(pool, @testThread, 1, n, 4, nCores/nJobs);
output1 = fetchOutputs(jobt1);
output2 = fetchOutputs(jobt2);
output3 = fetchOutputs(jobt3);
output4 = fetchOutputs(jobt4);
delete(pool);
6 Using MATLAB across multiple nodes
To use MATLAB across multiple nodes, you need to have the MATLAB Parallel Server, which often requires an additional license. If it is installed, one can set up MATLAB so that parfor will distribute its work across multiple nodes. Details may vary depending on how Parallel Server is set up on your system.