Я пишу код C ++ MPI для класса параллельных вычислений.Мой код работает, и я изменил назначение, но код использует намного больше памяти, чем я ожидал.По мере увеличения числа процессоров требования к памяти на узел быстро растут.Это первая настоящая программа на C / C ++ или MPI, которую мне когда-либо приходилось писать, поэтому я думаю, что где-то произошла утечка памяти.Может кто-нибудь взглянуть на этот код и сказать мне, где?Всякий раз, когда я создаю переменную, используя new, я удаляю ее, поэтому я не уверен, что еще мне нужно искать.Я полагаю, что некоторые проблемы могут быть вызваны объектами, которые я создаю, но следует ли вызывать деструкторы для этих объектов в конце их области действия, чтобы освободить память, выделенную в куче?Я родом из Java, и большая часть моего C / C ++ самоучка, поэтому мне сложно справиться с управлением собственной памятью.
Проблема очень проста.У меня есть матрица (хранится как одномерный вектор) размером MSIZE * MSIZE
.Каждый процессор отвечает за некоторый непрерывный блок данных.Затем я запускаю 500 итераций, где каждый некраевой элемент A[r][c]
установлен на максимум A[r][c], A[r+1][c], A[r-1][c], A[r][c+1], A[r-1][c-1]
.Новое значение A[r][c]
не сохраняется до тех пор, пока не завершится весь процесс обновления для этих итераций.Процессоры должны передавать значения, находящиеся на границах, другим процессорам.
Вот мой код (я думаю, что проблема возникает где-то здесь, но если вы хотите увидеть остальную часть кода (в основном вспомогательные функции и функции инициализации), дайте мне знать, и я опубликую его):
#include <math.h>
#include "mpi.h"
#include <iostream>
#include <float.h>
#include <math.h>
#include <assert.h>
#include <algorithm>
#include <map>
#include <vector>
#include <set>
using namespace std;
#define MSIZE 4000
#define TOTAL_SIZE (MSIZE * MSIZE)
#define NUM_ITERATIONS 500
int myRank;
int numProcs;
int start, end;
int numIncomingMessages;
double startTime;
vector<double> a;
map<int, set<int> > neighborsToNotify;
/*
* Send the indices that have other processors depending on them to those processors.
* Once the messages have been sent, receive messages until we've received all the messages
* we are expecting to receive.
*/
void doCommunication(){
int messagesReceived = 0;
map<int, set<int> >::iterator iter;
for(iter = neighborsToNotify.begin(); iter != neighborsToNotify.end(); iter++){
int destination = iter->first;
set<int> indices = iter->second;
set<int>::iterator setIter;
for(setIter = indices.begin(); setIter != indices.end(); setIter++){
double val = a.at(*setIter);
MPI_Bsend(&val, 1, MPI_DOUBLE, destination, *setIter, MPI_COMM_WORLD);
}
MPI_Status s;
int flag;
MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &s);
while(flag){
double message;
MPI_Recv(&message, 1, MPI_DOUBLE, s.MPI_SOURCE, s.MPI_TAG, MPI_COMM_WORLD, &s);
a.at(s.MPI_TAG) = message;
messagesReceived++;
MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &flag, &s);
}
}
while(messagesReceived < numIncomingMessages){
MPI_Status s;
MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &s);
double message;
MPI_Recv(&message, 1, MPI_DOUBLE, s.MPI_SOURCE, s.MPI_TAG, MPI_COMM_WORLD, &s);
a.at(s.MPI_TAG) = message;
messagesReceived++;
}
}
/*
* Perform one timestep of iteration.
*/
void doIteration(){
int pos;
vector<double> temp;
temp.assign(end - start + 1, 0);
for(pos = start; pos <= end; pos++){
int i;
double max;
if(isEdgeNode(pos))
continue;
int dependents[4];
getDependentsOfPosition(pos, dependents);
max = a.at(pos);
for(i = 0; i < 4; i++){
if(isInvalidPos(dependents[i]))
continue;
max = std::max(max, a.at(dependents[i]));
}
temp.at(pos - start) = max;
}
for(pos = start; pos <= end; pos++){
if(! isEdgeNode(pos)){
a.at(pos) = temp.at(pos - start);
}
}
}
/*
* Compute the checksum for this processor
*/
double computeCheck(){
int pos;
double sum = 0;
for(pos = start; pos <= end; pos++){
sum += a.at(pos) * a.at(pos);
}
return sum;
}
int main(int argc, char *argv[]) {
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
MPI_Comm_size(MPI_COMM_WORLD, &numProcs);
findStartAndEndPositions();
initializeArray();
findDependentElements();
MPI_Barrier(MPI_COMM_WORLD);
if(myRank == 0){
startTime = MPI_Wtime();
}
int i;
for(i = 0; i < NUM_ITERATIONS; i++){
if(myRank == 0)
cout << ".";
doCommunication();
MPI_Barrier(MPI_COMM_WORLD);
doIteration();
}
double check = computeCheck();
double receive = 0;
MPI_Reduce(&check, &receive, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
if(myRank == 0){
cout << "n = " << MSIZE << " and p = " << numProcs << "\n";
cout << "The total time was: " << MPI_Wtime() - startTime << " seconds \n";
cout << "The checksum was: " << receive << " \n";
}
MPI_Finalize();
return 0;
}