0

我并行化了下面的代码,但仿真时间实际上是串行代码的 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
4

1 回答 1

0

不能确定是不是这个原因,但是如果代码的某些部分最终被并行化,而其他部分则不能,它将产生大量开销而没有任何加速。有关切片的更详细讨论,请参见此处的问答。

基本上,如果你有parfor一个变量,那么在右侧使用的jj每个语句也应该在左侧使用 - 这样,“作业”可以在不同的处理器之间划分,每个处理器处理阵列的一部分并行。只要那没有发生,例如在您的台词中jjjj

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 没有这个概念 - 但存在于 OMP 中)。

我看不到循环中p的索引位置parfor......它似乎是在内部循环之外更新,它应该无关紧要。

您可能会发现使用并行分析器http://www.mathworks.com/help/distcomp/profiling-parallel-code.html分析您的代码很有帮助- 这将很有启发性。

于 2013-12-20T02:48:48.130 回答