我将以下代码并行化,但模拟时间实际上比串行代码长400-500倍。我能想到的唯一原因可能是导致这一消息'变量x被索引但未在parfor循环中切片,'变量p被索引但未在parfor循环中切片。任何人都可以验证这是模拟时间大幅增加的原因还是我将代码并行化的方式。
p =(1,i)和x(1,i)是具有预先设定值的矩阵。
nt=1;
nc=32;
time(1,1) = 0.0;
for t=dt:dt:0.1
nt=nt+1;
time(1,nt) = t;
disp(t);
for ii=2:nc
mytemp=zeros(1,ii);
dummy=0.0;
parfor jj=1:nc+1
if ii==jj % skipped
continue;
end
dxx = x(1,jj) - x(1,ii);
rr=abs(dxx);
if rr < re
dummy(jj) = (p(nt-1,jj)-p(nt-1,ii))*kernel(rr,re,ktype)*rr;
mytemp(jj) = kernel(rr,re,ktype)*rr;
%sumw(1,ii) = sumw(1,ii) + kernel(rr,re,1);
end
end
mysum = sum(dummy);
zeta(1,ii)=sum(mytemp);
lapp(1,ii) = 2.0*dim*mysum/zeta(1,ii);
p(nt,ii) = p(nt-1,ii) + dt*lapp(1,ii);
end
% update boundary value
p(nt,1) = function_phi(0,t);
p(nt,nc+1) = function_phi(1,t);
end
答案 0 :(得分:0)
无法确定是什么原因,但如果代码的某些部分最终被并行化而其他部分无法并行,则会在没有任何加速的情况下产生大量开销。有关切片的更详细讨论,请参阅Q&amp; A here。
基本上,如果您的parfor
变量为jj
,则右侧使用jj
的每个语句也应使用jj
左手边 - 这样,“作业”可以在不同的处理器之间划分,每个处理器并行处理阵列的一部分。一旦发生这种情况,例如你的行
dxx = x(1,jj) - x(1,ii);
rr=abs(dxx);
你打破了范式。 400倍慢?我不知道 - 但警告很清楚。
顺便说一句,前两行可以通过计算rr(jj)
进行整合(尽管您不需要数组):
rr(jj) = abs(x(1,jj) - x(1,ii));
然后在循环中使用该值而不是rr
。这有点像为循环的每个副本都有一个private
变量(我不认为Matlab有这个概念 - 但是exists in OMP)。
我没有看到p
循环中parfor
被编入索引的位置...它似乎是在内循环之外的更新,它应该不重要。
您可能会发现使用并行分析器http://www.mathworks.com/help/distcomp/profiling-parallel-code.html对代码进行分析会很有帮助 - 这将是有益的。