没有mpi指令的程序在mpirun中非常慢



我现在正在写一个学习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秒。是的,在一个线程中。

在远程主机上(Sun OS 5.11,双核CPU, 8vcpu),我用

编译它
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架构吗?

主要答案在于内存管理。

看这些行

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秒。

但是我仍然不知道其他的时间泄漏在哪里。也许我应该优化其中一个矩阵的循环

相关内容

  • 没有找到相关文章