我现在正在写一个研究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的架构吗?
答案 0 :(得分: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秒。
但我还是不知道其他时间在哪里泄漏。也许我应该以某种方式优化循环矩阵之一。