Domanda

Sto cercando di scrivere un auto deframmentazione gestore di memoria per cui un semplice allocatore di incremento heap viene utilizzato in combinazione con un semplice programma di deframmentazione di compattazione.

Lo schema di massima sarebbe quella di allocare blocchi di partenza presso l'indirizzo di memoria più basso andando verso l'alto e mantenere le informazioni contabilità a partire dall'indirizzo più alta memoria di lavoro verso il basso.

Il gestore di memoria sarebbe passato indietro puntatori intelligenti - intrusive_ptr di spinta di sembra il più ovvio per le struct libro di mantenimento che sarebbe poi si dirigerà verso il blocco di memoria reale dando così un livello di indirezione in modo che i blocchi possono essere facilmente spostati.

La deframmentazione sarebbe compattare giù mucchio partendo Preferiti 'generazione' per accelerare il processo e solo deframmentazione una quantità fissa di memoria alla volta. puntatori prime ai blocchi stessi sarebbero valide fino al prossimo passaggio di deframmentazione e così potrebbero essere passati in giro liberamente fino a quando una tale performance migliorando il tempo.

L'applicazione specifica per questo è la programmazione console di gioco e così, all'inizio o alla fine di ogni frame un passaggio di deframmentazione potrebbe essere fatto relativamente al sicuro.

Quindi la mia domanda è qualcuno ha usato questo tipo di piano di ripartizione in combinazione con STL sarebbe solo colpo completamente STL a parte come sospetto. Posso vedere std :: list lavorare a livello intrusive_ptr ma per quanto riguarda l'assegnazione della lista stl nodi stessi Esiste un modo per ignorare i puntatori successivo / precedente per essere intrusive_ptr se stessi è O sono solo intenzione di avere un allocatore mucchio di serie al fianco di questo uno più dinamico.

È stato utile?

Soluzione

Se avete intenzione di essere in movimento oggetti intorno in memoria, allora non si può fare questo completamente generico. Lei sarà solo in grado di fare questo con gli oggetti che so che potrebbero essere spostati. È inoltre necessario un meccanismo di bloccaggio. Quando una funzione viene chiamata su un oggetto, allora non può essere spostato.

Il motivo è che l'intero modello C ++ si basa su oggetti seduti a punti fissi nella memoria, quindi se un filo stava chiamando un metodo su un oggetto, questa discussione è stata messa in pausa e l'oggetto spostato, il disastro avrebbe colpito quando il thread ripreso.

Qualsiasi oggetto che conteneva un puntatore di memoria prima per un altro oggetto che potrebbe essere spostato (compreso un sotto-oggetto stesso) non funzionerebbe.

Un tale sistema di gestione della memoria può funzionare, ma bisogna stare molto attenti. È necessario essere rigorosi su maniglie di attuazione, e il handle-> puntatore semantica di blocco.

Per i contenitori STL, è possibile personalizzare l'allocatore, ma ha bisogno ancora di restituire puntatori fissi di memoria prime. Non si può restituire un indirizzo che potrebbe muoversi. Per questo motivo, se si sta utilizzando contenitori STL, devono essere contenitori di maniglie, ei nodi stessi saranno ordinaria memoria allocata dinamicamente. Potreste scoprire che si troppo in testa nella indiretto manico e avere ancora problemi nella frammentazione delle collezioni gestire rispetto si guadagna utilizzando STL.

Utilizzare contenitori in grado di comprendere le vostre maniglie direttamente potrebbe essere l'unica via da seguire, e anche allora ci può essere ancora un sacco di spese generali rispetto a un'applicazione C ++ che utilizza oggetti tradizionali fissi nella memoria.

Altri suggerimenti

contenitori STL sono realizzati tramite puntatori nudi.

È possibile specificare un allocatore personalizzato quando li si crea un'istanza (in modo che inizializza i puntatori utilizzando l'allocatore), ma (perché i valori assegnati sono memorizzati in puntatori nudo) non si sa dove questi puntatori sono, e quindi si non può cambiare in un secondo momento.

Invece, si potrebbe prendere in considerazione l'attuazione di un sottoinsieme del STL te stesso:. Vostre versioni dei contenitori STL potrebbe poi essere implementato con puntatori gestiti

Una tecnica alternativa che è abbastanza noto è il href="http://en.wikipedia.org/wiki/Buddy_memory_allocation" sistema del compagno . Si dovrebbe dare un'occhiata a quello per l'ispirazione supplementare.

Se questo è per la programmazione console di gioco è molto più facile di vietare non-con ambito allocazioni di memoria dinamica in fase di esecuzione. E al tempo di avvio, ma questo è un po 'difficile da raggiungere.

Il mio prendere su questo, è che se deve avere paura di frammentazione, che significa che si sta giocoleria in giro con pezzi di dati che sono una grande frazione della vostra memoria, e da questa virtù da sola, non si può avere molti di loro. Sapete già che cosa saranno questi? Forse sarebbe meglio fare un passo verso il basso di un livello e prendere decisioni più specifiche, in tal modo impedendo meno dall'altra codice e il generale andamento della vostra applicazione?

Una lista è un eccezionale cattivo esempio di mettere in un gestore di memoria deframmentazione, perché è un gruppo di piccoli pezzi, come lo sono la maggior parte altre strutture di dati STL. Se si esegue questa operazione, avrà tutti i tipi di cattivi ovvie implicazioni - tra cui le prestazioni del vostro programma di deframmentazione che va verso il basso, anche il costo indiretto etc. Le uniche strutture in cui ha senso IMO sono quelli contigious - serie, deque, pezzo principale della tabella hash , quelle cose, e solo al di là di una certa dimensione, e solo dopo che sono gonna non essere ridimensionati più. Questo tipo di cose chiamata, ancora una volta, per soluzioni specifiche, invece di quelli generici.

Commento indietro come tutto risulta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top