2

現在MPIを勉強するプログラムを書いています。正方行列を乗算するプログラムを書きます。

long **multiplyMatrices(long **matrix1, long **matrix2, long capacity)
{
    long **resultMatrix = new long*[capacity];

    for (long i = 0; i < capacity; ++i) {
        resultMatrix[i] = new long[capacity];
    }

    for (long i = 0, j, k; i < capacity; ++i) {
        for (j = 0; j < capacity; ++j) {
            resultMatrix[i][j] = 0;

            for (k = 0; k < capacity; ++k) {
                resultMatrix[i][j] = resultMatrix[i][j] + matrix1[i][k] * matrix2[k][j];
            }
        }
    }

    return resultMatrix;
}

どこでcapacity == 1000

ローカルホスト (Mac Mini 2012、Core i7、OS X 10.8.2) で、LLVM を使用して XCode でこのコードをコンパイルします。計算には 17 秒かかります。はい、1 つのスレッドで。

リモートホスト(Sun OS 5.11、デュアルコアCPU、8 vCPU)でコンパイルします

g++ -I/usr/openmpi/ompi-1.5/include -I/usr/openmpi/ompi-1.5/include/openmpi -O2 main.cpp -R/opt/mx/lib -R/usr/openmpi/ompi-1.5/lib -L/usr/openmpi/ompi-1.5/lib -lmpi -lopen-rte -lopen-pal -lnsl -lrt -lm -ldl -lsocket -o main

あるいは単に

g++ -O2 main.cpp -o main

しかし...mpirun mainこれを計算するには152秒かかります...何が問題なのですか? 何か不足していますか?それはサーバーのCPUのアーキテクチャに関するものですか?

4

1 に答える 1

0

主な答えはメモリ管理にあります。

それらの行を見てください

long **resultMatrix = new long*[capacity];

for (long i = 0; i < capacity; ++i) {
    resultMatrix[i] = new long[capacity];
}

すべての行は、ブロック全体としてではなく、メモリのさまざまな場所にあります。Mac Mini で物理メモリがどのように表示されるかはわかっています — 2 枚のプラスチックですが、サーバーでは異なるホスト (クラスタ) である可能性さえあります。

これを修正してみましょう。

long **allocateMatrix(long capacity)
{
    // Allocating a vector of pointers to rows
    long **matrix = (long **)malloc(capacity * sizeof(long *));

    // Allocating a matrix as a whole block
    matrix[0] = (long *)malloc(capacity * capacity * sizeof(long));

    // Initializing a vector of pointers with rows of addresses
    long *lineAddress = matrix[0];
    for(long i = 0; i < capacity; ++i) {
        matrix[i] = lineAddress;
        lineAddress += capacity;
    }

    return matrix;
}

void deallocateMatrix(long **matrix, long capacity)
{
    free(matrix[0]);
    free(matrix);
}

これにより、Mac Mini で実行されるコードは 9.8 秒、サーバーでは 58 秒に短縮されます。

しかし、他のタイムリークがどこにあるのかはまだわかりません。たぶん、マトリックスのループを最適化する必要があります。

于 2012-12-25T05:03:36.220 に答える