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

それが理由かどうかは定かではありませんが、コードの一部が並列化され、他の部分が並列化されない場合、高速化することなく多くのオーバーヘッドが発生します。たとえば、スライスの詳細については、こちらの Q&A を参照してください。

基本的に、parforwith 変数がある場合、右側で使用されるjjすべてのステートメントは左側でも使用する必要があります。そのようにして、「ジョブ」を異なるプロセッサ間で分割し、それぞれが取り組むことができます。配列の一部を並列に。それが起こらないとすぐに、たとえばあなたのラインでjjjj

dxx = x(1,jj) - x(1,ii);
rr=abs(dxx);

あなたはパラダイムを壊します。400倍遅い?それについてはわかりませんが、警告はかなり明確です。

ところで、最初の 2 行は計算によって統合できます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 に答える