Matlab中的并行运算常用的有 parfor-loop代替for-loop加速计算,这里parfor就是parallel的意思。
client把任务分配给多个workers,在一个循环中同时运行,等所有workers运行完返回结果,然后对结果进行整合。
一个迭代就是指执行一次循环体。每一个worker独立地按照一定的次序迭代。
官方原图:
parfor 把for循环中的迭代分成多个部分同时运行。这里有两个问题:
(1)什么样的任务能够拆分并行运行?
(2)怎么拆分?
(3)怎么把for-loop改写成parfor-loop
关于第一个问题:什么样的任务能够拆分并行运行?
每一个迭代是独立的,就是说上一个循环的结果对下一个循环的结果没有影响。下面给出的例子就不行,在计算时要用到上一次迭代的结果.
tic
ntasks = 200;
A = 500;
a = zeros(ntasks);
for i = 1:ntasks
a(m) = max(abs(eig(rand(A))));
if i > 2
b(i) = a(i)+a(i-1);
end
end
toc
改成parfor时出错
tic
ntasks = 200;
A = 500;
a = zeros(ntasks);
for i = 1:ntasks
a(i) = max(abs(eig(rand(A))));
if i > 2
b(i) = a(i)+a(i-1);
end
end
toc
关于第二个问题:怎么拆分?
这里介绍parfor这个函数的参数
parfor loopVar = initVal:endVal; statements; end
parfor (loopVar = initVal:endVal,M); statements; end
这里M指定多少个worker,一般系统默认把可以使用的都用上。
loopVar,initVal,endVal与for循环一样的。
endVal 可以理解为把整个任务分为几个部分去运行,endVal 可以大于电脑的核数或者说worker。
所以这个函数并没有说明是怎么拆分数据的。
官方的说法:Loop iterations are executed in parallel in a nondeterministic order.
可以理解为随机拆分执行吗?
关于第三个问题:怎么把for-loop改写成parfor-loop
tic
n = 200;
A = 500;
a = zeros(n);
for i = 1:n
a(i) = max(abs(eig(rand(A))));
end
toc
tic
n = 200;
A = 500;
a = zeros(n);
parfor i = 1:n
a(i) = max(abs(eig(rand(A))));
end
toc
查看给每一个worker分配的数据:
tic
ticBytes(gcp);
n = 200;
A = 500;
a = zeros(n);
parfor i = 1:n
a(i) = max(abs(eig(rand(A))));
end
tocBytes(gcp)
toc
参考:
https://ww2.mathworks.cn/help/distcomp/interactively-run-a-loop-in-parallel.html#responsive_offcanvas
https://ww2.mathworks.cn/help/distcomp/parfor.html
https://ww2.mathworks.cn/help/distcomp/interactively-run-a-loop-in-parallel.html#responsive_offcanvas