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

好的,在 localhost(Mac Mini 2012、Core i7、OS X 10.8.2)上,我使用 LLVM 在 XCode 中编译此代码。计算需要 17 秒。是的,在一个线程中。

在远程主机(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 上是如何呈现的——两块塑料,但在服务器上它甚至可能是不同的主机(集群)。

现在我们将尝试解决这个问题。

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 回答