我正在比较两个块之间的执行时间,一个使用parfor
,另一个通过发出parfeval
并获取输出来执行相同的操作:
parfor k = 1:N
a = rand(5000);
b = inv(a);
end
VS。
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);
end
parfor
始终更快。任何见解为什么会这样?我的简单理解是parfor
基本上将每个循环作为并行作业运行。
答案 0 :(得分:0)
您的理解是正确的。
通过运行带有parfeval
的循环,您无法获得并行计算工具箱的强大功能。
在第一种情况下,5000 x 5000矩阵的逆矩阵似乎是计算密集型的,但是MATLAB针对这些类型的操作(特别是矩阵运算)进行了优化。
众所周知,MATLAB的一个弱点是循环,在第二个用例中使用parfeval
意味着您正在顺序地评估每个矩阵的逆(即使您正在并行化逆函数)。
通过使用parfor
,您可以获得并行化代码最耗时方面的优势。
只有在size(a) >> N
您看到parfor
的表现优于parfeval
的情况下,我才会冒险。
修改强>
@Adriaan也提出a great point。与大多数MATLAB函数一样,inv
也是一个隐式并行函数。
答案 1 :(得分:0)
在第二种情况下,您没有并行化逆,这可能导致两者之间的任何差异。
对我来说,以下两个选项花费的时间相同。
初始化:
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;