一般信息
很多功能都有内置隐式多线程 http://mathworks.com/products/parallel-computing/builtin-parallel-support.html,制作一个parfor
使用这些函数时,循环并不比串行更有效for
循环,因为所有核心都已被使用。parfor
在这种情况下实际上会造成损害,因为它具有分配开销,同时与您尝试使用的函数一样并行。
不使用隐式多线程函数之一时parfor http://mathworks.com/help/distcomp/parfor.html基本上建议在两种情况下使用:循环中进行大量迭代(即,例如1e10
),或者如果每次迭代都需要很长时间(例如,eig(magic(1e4))
)。在第二种情况下,您可能需要考虑使用spmd http://mathworks.com/help/distcomp/spmd.html(慢于parfor
在我的经验中)。原因parfor
比a慢for http://mathworks.com/help/distcomp/for.html短范围或快速迭代的循环是正确管理所有工作人员所需的开销,而不是仅仅进行计算。
Check 这个问题 https://stackoverflow.com/questions/32095552/sending-data-to-workers有关在不同工作人员之间分割数据的信息。
标杆管理
Code
考虑以下示例以查看行为for
与parfor
。如果您还没有打开并行池,请先打开它:
gcp; % Opens a parallel pool using your current settings
然后执行几个大循环:
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[-]';
然后做同样的事情parfor
代替for
。您会注意到每次迭代的平均时间增加(对于我的情况,从 0.27 秒增加到 0.39 秒)。但请注意,parfor
使用了所有可用的工人,因此总时间(sum(Time)
)必须除以计算机的核心数量。因此,对于我的情况,总时间从大约 270 秒减少到 49 秒,因为我有一个八核处理器。
因此,虽然每次单独迭代的时间都会增加parfor
关于使用for
,总时间大大减少。
Results
这张图显示了我刚刚在我的家用电脑上运行的测试结果。我用了n=1000
and eig(500)
;我的计算机具有四核 I5-750 2.66GHz 处理器,运行 MATLAB R2012a。正如您所看到的,并行测试的平均值徘徊在 0.29 秒左右,并且有很大的差距,而串行代码则相当稳定在 0.24 秒左右。然而,总时间从 234 秒下降到 72 秒,加速了 3.25 倍。这不完全是 4 的原因是内存开销,用每次迭代花费的额外时间来表示。内存开销是由于 MATLAB 必须检查每个内核正在执行的操作并确保每个循环迭代仅执行一次并且数据被放入正确的存储位置。