0
s=1

r=m=n=o=p=q=u=t=19

myfile = fopen ("sequence2.txt", "w", "ieee-le");

for a=0:1

  if(a==1)

      r=5

  endif

  for b=0:r

    if(a==1 && b==5)

    m=11

    endif   

for c=0:m

n=o=19

  for d=0:1

if(d==1)

  n=5

  endif

for e=0:n

  if(d==1 && e==5)

    o=11

        endif   

  for f=0:o

    p=q=19

    for g=0:1

      if(g==1)

    p=5

      endif

      for h=0:p

    if(g==1 && h==5)

      q=11

        endif   

    for i=0:q

      t=u=19

      for j=0:1

        if(j==1)

          t=5

        endif

        for k=0:t

          if(j==1 && k==5)

        u=11

              endif   

          for l=0:u



        s=s+1

        fputs(myfile,num2str(a));

        fputs(myfile,".");

        fputs(myfile,num2str(b)); 

        fputs(myfile,".");

        fputs(myfile,num2str(c));

        fputs(myfile,":");

        fflush(stdout);

        fputs(myfile,num2str(d));

        fputs(myfile,".");

        fputs(myfile,num2str(e)); 

        fputs(myfile,".");

        fputs(myfile,num2str(f));

        fputs(myfile,":");

        fflush(stdout);

        fputs(myfile,num2str(g));

        fputs(myfile,".");

        fputs(myfile,num2str(h)); 

        fputs(myfile,".");

        fputs(myfile,num2str(i));

        fputs(myfile,":");

        fflush(stdout);

        fputs(myfile,num2str(j));

        fputs(myfile,".");

        fputs(myfile,num2str(k)); 

        fputs(myfile,".");

        fputs(myfile,num2str(l));

        fputs(myfile,"\n");

        fflush(stdout);

        end

          end

        end

      end

        end

      end

    end

      end 

end

  end

end 

  end

上記のオクターブのコードは、テキスト ファイルに書き込む数列を生成するためのものです。約 2^36 の数値を生成しているため、実行が完了するまでに数日かかります。このコードを hpc で並列化する方法を教えてください。

4

1 に答える 1

1

これを並列化する必要はないかもしれません。コンパイル済み言語に移行することで、これを約 10000 倍高速化できます。(真剣に;以下を参照してください。)オクターブまたはmatlabでさえ、糖蜜がこれを実行しているため遅くなります。これらは大規模な行列演算には最適ですが、if ステートメントを含む大量のネストされたループは、ゆっくりとゆっくりと実行されます。通常、Octave/Matlab コードを FORTRAN に移行することをお勧めしますが、基本的に C ステートメントで記述されたファイル I/O を既に取得しているため、このコードの C 版はほとんどそれ自体を記述します。

#include <stdio.h>

int main(int argc, char **argv) {
    int a,b,c,d,e,f,g,h,i,j,k,l;
    int s,r,m,n,o,p,q,u,t;
    FILE *myfile;

    s=1;

    r=m=n=o=p=q=u=t=19;

    myfile = fopen ("sequence2-c.txt", "w");
    for (a=0; a<=1; a++) {

        if (a == 1)
            r = 5;

        for (b=0; b<=r; b++) {
            if (a == 1 && b == 5) 
                m = 11;

            for (c=0; c<=m; c++) {
                n = o = 19;

                for (d=0; d<=1; d++) {
                    if (d==1)
                        n = 5;

                    for (e=0; e<=n; e++) {
                        if (d==1 && e == 5)
                            o = 11;


                        for (f=0; f<=o; f++) {
                            p = q = 19;

                            for (g=0; g<=1; g++) {
                                if (g == 1)
                                    p = 5;


                                for (h=0; h<=p; h++) {
                                    if (g == 1 && h==5) 
                                        q = 11;                                           

                                    for (i = 0; i<=q; i++) {
                                        t=u=19;

                                        for (j=0; j<=1; j++) {
                                            if (j==1)
                                                t=5;

                                            for (k=0; k<=t; k++) {
                                                if (j==1 && k==5)
                                                    u=11;                                                    

                                                for (l=0;l<=u;l++){
                                                    s++;                                                        
                                                    fprintf(myfile,"%d.%d.%d:%d.%d.%d:%d.%d.%d:%d.%d.%d\n",a,b,c,d,e,f,g,h,i,j,k,l);

                                                }
                                            }
                                        }
                                    }
                                }
                            }                            
                        }
                    }
                }
            }
        }
    }
    return 0;
}

上記のオクターブ コードとこの C コード (-O3 でコンパイル) をそれぞれ 1 分間実行すると、オクターブ コードはシーケンスで約 2,163 項目を通過し、コンパイルされた C コードは 23,299,068 項目を通過しました。それでいいです。

並列化に関しては、これを独立した部分に分割するのは簡単ですが、負荷分散は特にうまくいきません。(たとえば) 26 個のプロセスを開始し、それらに (a=0,b=0), (a=0,b=1)...,(a=0,b=19),(a=1, b=0), (a=1,b=1),.. (a=1,b=5)、それらはすべて独立して実行でき、すべて完了したら結果を連結できます。唯一の欠点は、a=0 ジョブの実行が a=1 ジョブよりもやや遅くなることですが、開始するには十分かもしれません。

于 2011-03-17T12:57:58.513 に答える