Программа без инструкций 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) я компилирую этот код в XCode с LLVM. Расчет занимает 17 секунд. Да, в одной теме.

На удаленном хосте (Sun OS 5.11, двухъядерный процессор, 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 секунды, чтобы вычислить это … Что не так? Я что-то пропустил? Это из-за архитектуры процессора сервера?

2

Решение

Основной ответ в управлении памятью.

Посмотри на эти строки

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 секунд.

Но я до сих пор не знаю, где другие утечки времени. Может мне стоит как-то оптимизировать зацикливание одной из матриц.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]