0

I have figured out some awesome ways of speeding up my MATLAB code: vectorizing, arrayfun, and basically just getting rid of for loops (not using parfor). I want to take it to the next step.

Suppose I have 2 function calls that are computationally intensive.

x = fun(a);
y = fun(b);

They are completely independent, and I want to run them in parallel rather than serially. I dont have the parallel processing toolbox. Any help is appreciated.

thanks

Chet
  • 18,421
  • 15
  • 69
  • 113
  • `arrayfun` for speeding up? I don't think so. A `for` loop is usually faster. As for parallelizing, see `matlabpool` / `parpool`: http://www.mathworks.es/es/help/distcomp/parpool.html – Luis Mendo Oct 02 '13 at 08:39
  • 1
    Note that the best speedups are usually not achieved by doing the calculations faster, but by (only) calculating the right things in the right way. – Dennis Jaheruddin Oct 02 '13 at 08:55
  • hopefully that clarified a little bit... – Chet Oct 02 '13 at 08:56
  • Luis, is that a little more clear? I'm pretty sure serial for loops are slower than using arrayfun (commonly known as map)... – Chet Oct 02 '13 at 08:58
  • I really dont understand why you guys are hating on this question so badly... – Chet Oct 02 '13 at 09:00
  • @Chet `arrafun` vs. `for`: See for example this: http://stackoverflow.com/questions/12522888/arrayfun-can-be-significantly-slower-than-an-explicit-loop-in-matlab-why – Luis Mendo Oct 02 '13 at 09:17
  • 1
    @LuisMendo There is actually a version of [`arrayfun`](http://www.mathworks.com/help/distcomp/arrayfun.html) in the Parallel Computing Toolbox, which utilizes GPUs to perform distributed computations, so it's probably wiser to understand if the question concerns it before dismissing it :) – Eitan T Oct 02 '13 at 10:09
  • @EitanT Oops, I didn't know about that version of `arrayfun`. – Luis Mendo Oct 02 '13 at 10:20

3 Answers3

4

If I am optimistic I think you ask "How Can I simply do parallel processing in Matlab". In that case the answer would be:

Parallel processing can most easily be done with the parallel computing toolbox. This gives you access to things like parfor.

I guess you can do:

parfor t = 1:2
   if t == 1, x = fun(a); end
   if t == 2, y = fun(b); end
end

Of course there are other ways, but that should be the simplest.

Community
  • 1
  • 1
Dennis Jaheruddin
  • 21,208
  • 8
  • 66
  • 122
4

The MATLAB interpreter is single-threaded, so the only way to achieve parallelism across MATLAB functions is to run multiple instances of MATLAB. Parallel Computing Toolbox does this for you, and gives you a convenient interface in the form of PARFOR/SPMD/PARFEVAL etc. You can run multiple MATLAB instances manually, but you'll probably need to do a fair bit of work to organise the work that you want to be done.

Edric
  • 23,676
  • 2
  • 38
  • 40
0

The usual examples involve parfor, which is probably the easiest way to get parallelism out of MATLAB's Parallel Computing Toolbox (PCT). The parfeval function is quite easy, as demonstrated in this other post. A less frequently discussed functionality of the PCT is the system of jobs and tasks, which are probably the most appropriate solution for your simple case of two completely independent function calls. Spoiler: the batch command can help to simplify creation of simple jobs (see bottom of this post).

Unfortunately, it is not as straightforward to implement; for the sake of completeness, here's an example:

% Build a cluster from the default profile
c = parcluster();

% Create an independent job object
j = createJob(c);

% Use cells to pass inputs to the tasks
taskdataA = {field1varA,...};
taskdataB = {field1varB,...};

% Create the task with 2 outputs
nTaskOutputs = 2;
t = createTask(j, @myCoarseFunction, nTaskOutputs, {taskdataA, taskdataB});

% Start the job and wait for it to finish the tasks
submit(j); wait(j);

% Get the ouptuts from each task
taskoutput = get(t,'OutputArguments');

delete(j); % do not forget to remove the job or your APPDATA folder will fill up!

% Get the outputs
out1A = taskoutput{1}{1};
out1B = taskoutput{2}{1};

out2A = taskoutput{1}{2};
out2B = taskoutput{2}{2};

The key here is the function myCoarseFunction given to createTask as the function to evaluate in the task objects to creates. This can be your fun or a wrapper if you have complicated inputs/outputs that might require a struct container.

Note that for a single task, the entire workflow above of creating a job and task, then starting them with submit can be simplified with batch as follows:

c = parcluster();
jobA = batch(c, @myCoarseFunction, 1, taskdataA,...
    'Pool', c.NumWorkers / 2 - 1, 'CaptureDiary', true);

Also, keep in mind that as with matlabpool(now called parpool), using parcluster requires time to startup the MATLAB.exe processes that will run your job.

Community
  • 1
  • 1
chappjc
  • 30,359
  • 6
  • 75
  • 132
  • I'm getting an warning of `myCoarseFunction` doesn't exists. –  May 27 '14 at 21:52
  • @AhsanAli This is an example. Say you have some function called `myCoarseFunction`, this is how you'd do it. – chappjc May 27 '14 at 22:21
  • please tell how to apply this on my code: ` parfor ii = 1:1000 p{ii,1}= repmat([2 4 5;],500,1); %suppose very big matrix pp{ii,1}=p{ii,1}*2; for jj = 1:100 p1{jj,1} = p{ii}* pp{ii}; p2{jj} = p{ii}* pp{ii}*p1{jj}; p3{jj} = p{ii}* pp{ii}*p1{jj}*p2{ii}; end Data(ii).data=([pp(ii,:),p1{:,1},p2,p3;])' ; Data(ii).label=cellfun(@(x) ['label' num2str(ii)] , num2cell(1:length(pp)+length(p1)+length(p2)+length(p3))', 'UniformOutput', false); end` –  May 27 '14 at 23:45