我比较了两个块之间的执行时间,一个使用parfor,另一个通过发出parfeval和获取输出来做同样的事情:
parfor k = 1:N
a = rand(5000);
b = inv(a);
end与
for k = 1:N
a = rand(5000);
F(k) = parfeval(p,'inv',1,a);
end
for k = 1:N
[completedIdx,value] = fetchNext(F);
fprintf(1,'%d ',completedIdx);
endparfor的速度始终如一。对于为什么会这样,有什么见解吗?我的理解很简单,parfor本质上是将每个循环作为一个并行作业运行。
发布于 2016-09-20 06:16:56
你的理解是正确的。
通过使用parfeval运行循环,您无法利用并行计算工具箱的强大功能。
在第一种情况下,5000x5000矩阵的求逆看起来像是计算密集型的,但是MATLAB针对这些类型的操作(特别是矩阵操作)进行了优化。
众所周知,MATLAB的一个弱点是循环,在您的第二个用例中使用parfeval意味着您将按顺序计算每个矩阵的逆(即使您正在并行化逆函数)。
通过使用parfor,您可以并行化代码中最耗时的部分。
我敢说,只有在size(a) >> N的情况下,您才会看到parfor被parfeval超越的情况。
编辑 @Adriaan也制作a great point。与大多数inv函数一样,MATLAB也是一个隐式并行化函数。
发布于 2019-05-27 18:39:21
两者之间的任何差异很可能是因为您在第二种情况下没有并行化相反的情况。
对我来说,以下两个选项需要相同的时间。
Init:
p = gcp;
N = p.NumWorkers;选项A:
tic;
b = zeros( N, 1 );
parfor k = 1 : N;
b( k ) = max( max( abs( inv( rand( 5000 ) ) ) ) );
end;
toc;选项B:
tic;
F = repmat(parallel.FevalFuture,N,1);
for k = 1:N;
F(k) = parfeval( p, @() max( max( abs( inv( rand( 5000 ) ) ) ) ), 1 );
end;
b = fetchOutputs( F );
toc;https://stackoverflow.com/questions/39582588
复制相似问题