Considerare un'applicazione MPI basata su due passaggi che chiameremo carico e globalReduce. Giusto per semplicità, il software viene descritto come tale, ma c'è molto di più in corso, quindi non si tratta semplicemente di un problema di Map/Reduce.Riduzione della dimensione heap di un programma C++ dopo un calcolo di grandi dimensioni
Durante il carico passo , tutti i ranghi in ogni dato nodo vengono accodate in modo tale che uno e solo un rango ha pieno accesso a tutti memoria del nodo. Il motivo di questo disegno deriva dal fatto che durante la fase di caricamento è in corso la lettura di un grande insieme di blocchi I/O e devono essere tutti caricati nella memoria prima dello a a livello locale. Chiameremo il risultato di questa riduzione locale una variabile denominata myRankVector. Una volta ottenuta la variabile myRankVector, i blocchi di I/O vengono rilasciati. La variabile myRankVector utilizza poca memoria, quindi mentre durante la sua creazione il nodo può utilizzare tutta la memoria, dopo il completamento il rank deve solo utilizzare 2-3 GB per contenere myRankVector.
Durante il globalReduce fase nel nodo, si prevede tutti i ranghi nel nodo avevano caricato alla corrispondente globalReduce.
Quindi ecco il mio problema, mentre mi sono assicurato che non ci siano perdite di memoria (programma usando i puntatori condivisi, ho controllato due volte con Valgrind, ecc.), Sono certo che l'heap rimane espanso anche dopo tutto i distruttori hanno rilasciato i blocchi di I/O. Quando il prossimo grado della coda viene a fare il suo lavoro, inizia a chiedere molta memoria proprio come faceva il rank precedente e, naturalmente, il programma ottiene il kill di Linux che produce "Out of memory: Kill process xxx (xxxxxxxx) score xxxx o sacrificare bambino ". È chiaro il motivo per cui questo è il caso, il secondo rango nella coda vuole usare tutta la memoria, ma il primo rango rimane con un grande ammasso.
Quindi, dopo aver impostato il contesto di questa domanda: esiste un modo per ridurre manualmente la dimensione dell'heap in C++ per liberare realmente la memoria non utilizzata?
Grazie.
non possono essere utili, ma si potrebbe sborsare/exec un programma bambino a fare il grande calcolo, allora il suo mucchio sarebbe "veramente liberato" quando è uscito. –
Dovremmo vedere il codice. La domanda è: perché il secondo grado non riutilizza la memoria liberata. –
Perché non si dispone di un singolo processo su ciascun nodo che in un ciclo su tutti i ranghi: 1) ottiene il vettore del rango, 2) lancia un thread separato, bloccato su un nucleo diverso, con accesso al vettore del rango? Quindi tutti i principali utilizzi della memoria si trovano nello stesso processo, risolvendo il problema mentre si utilizza ancora il parallelismo. –