0

私は単純なコードを持っています:

double eps;
A[N][N][N]; 

    ...


        for(i=1; i<=N-2; i++)
            for(j=1; j<=N-2; j++)
                for(k=1; k<=N-2; k++)
                {
                    A[i][j][k] = (A[i-1][j][k]+A[i+1][j][k])/2.;
                }
        for(i=1; i<=N-2; i++)
            for(j=1; j<=N-2; j++)
                for(k=1; k<=N-2; k++)
                {
                    A[i][j][k] = (A[i][j-1][k]+A[i][j+1][k])/2.;
                }
        for(i=1; i<=N-2; i++)
            for(j=1; j<=N-2; j++)
                for(k=1; k<=N-2; k++)
                {
                    double e;
                    e=A[i][j][k];
                    A[i][j][k] = (A[i][j][k-1]+A[i][j][k+1])/2.;
                    eps=Max(eps,fabs(e-A[i][j][k]));
                }

そして、MPI を使用して並列コードを作成する必要があります。

わかりました、どうすればいいですかeps- どこでも計算する必要があるのはグローバル変数です。そのため、ローカル変数を作成し、それを計算して、各ノードから結果を返します。または減らしてください。

しかし、マトリックスをどうするAか? すべてのノードで共有する必要があります。すべてのトリプルfor構築を同期する方法は? (use see の場合、その現在のA[i][j][k]-element は、その隣の使用法で計算されます - left and right A[i-1][][] A[i+1][][]or top and bottom A[][j+1][] A[][j-1][]or front and back A[][][k-1] A[][][k+1])

ありがとうございました!

初版:

for私の最初の解決策は、次のようなインデックスからの依存関係を最小限に抑えるために構造を置き換えることです。

        for(j=1; j<=N-2; j++)
            for(k=1; k<=N-2; k++)
//MPI here, Send processor (j,k) - coordinates of vector to compute next statement
                for(i=1; i<=N-2; i++)
                {
                    A[i][j][k] = (A[i-1][j][k]+A[i+1][j][k])/2.;
                }

等々:

        for(i=1; i<=N-2; i++)
            for(k=1; k<=N-2; k++)
                for(j=1; j<=N-2; j++)
//here (i,k) is free dimensions, dependency only from j. send vector(i,k) to every processor
                {
                    A[i][j][k] = (A[i][j-1][k]+A[i][j+1][k])/2.;
                }

        for(i=1; i<=N-2; i++)
            for(j=1; j<=N-2; j++)
                for(k=1; k<=N-2; k++)
//dependency only from k, (i,j) are free. send it to processor
                {
                    double e;
                    e=A[i][j][k];
                    A[i][j][k] = (A[i][j][k-1]+A[i][j][k+1])/2.;
                    eps=Max(eps,fabs(e-A[i][j][k]));
                }
4

1 に答える 1

3

あなたのアルゴリズムは、3DFFTアルゴリズムと非常によく似たデータ依存性を示します。データをどのように配布することを選択したとしても、それはループの1つに最適な配布ではありません。たとえば、k軸に沿って分散する場合、最初のループと2番目のループを並行して実行できますが、最後のループを実行することはできません。

解決策は、最後のループの前に行列を転置することです。MPI_ALLTOALL分散マトリックスのグローバル転置は、通常、マトリックスが同じサイズのチンクに分割されているかどうかに応じて、またはのいずれかで、オールツーオール操作を使用して実行MPI_ALLTOALLVされます(これは、通常、マトリックスサイズがMPIプロセスの数で割り切れるかどうかによって異なります)。か否か)。ジョナサン・ドゥルシによるこの優れた答えを見てください。2Dの場合ですが、3Dにも簡単に拡張できます。

于 2012-11-23T12:34:23.703 に答える