Ho un'applicazione Visual Studio 2008 C++ in cui sto utilizzando un allocatore personalizzato per contenitori standard in modo che la loro memoria provenga da un file mappato in memoria anziché dall'heap. Questo allocatore è usato per 4 casi d'uso differenti:suggerimenti per migliorare un'implementazione dell'algoritmo allocatore
- 104-byte struttura di dimensioni fisse
std::vector< SomeType, MyAllocator<SomeType> > foo;
- 200 byte dimensione fissa struttura
- 304 byte struttura dimensione fissa
- stringhe n byte
std::basic_string< char, std::char_traits<char>, MyAllocator<char> > strn;
Devo essere in grado di allocare circa 32 MB totali per ciascuno di questi.
L'allocatore tiene traccia dell'utilizzo della memoria utilizzando un std::map
di puntatori alle dimensioni di allocazione. typedef std::map< void*, size_t > SuperBlock;
Ogni SuperBlock rappresenta 4MB di memoria.
C'è uno std::vector<SuperBlock>
di questi nel caso in cui un SuperBlock non sia abbastanza spazio.
L'algoritmo utilizzato per l'allocatore è questa:
- Per ogni SuperBlock: C'è spazio alla fine del superblocco? mettere l'assegnazione lì. (veloce)
- In caso contrario, cercare all'interno di ciascun SuperBlock uno spazio vuoto di dimensioni sufficienti e collocare l'allocazione lì. (lento)
- Ancora niente? allocare un altro SuperBlock e inserire l'allocazione all'inizio del nuovo SuperBlock.
Sfortunatamente, il passaggio 2 può diventare MOLTO lento dopo un po '. Man mano che le copie degli oggetti vengono create e le variabili temporanee distrutte, ottengo molta frammentazione. Ciò causa molte ricerche approfondite all'interno della struttura della memoria. La frammentazione è in discussione perché ho una quantità limitata di memoria con cui lavorare (vedi nota sotto)
Qualcuno può suggerire miglioramenti a questo algoritmo che velocizzerebbe il processo? Ho bisogno di due algoritmi separati (1 per le allocazioni a dimensione fissa e uno per l'allocatore di stringhe)?
Nota: Per coloro che hanno bisogno di una ragione: sto usando questo algoritmo in Windows Mobile, dove c'è un limite di slot processo di 32MB al mucchio. Quindi, il solito std::allocator
non lo taglierà. Devo mettere le allocazioni nell'area di memoria grande da 1 GB per avere spazio sufficiente e questo è ciò che fa.
Buona idea per combinare dimensioni fisse e dimensioni variabili. Ho appena implementato questo ed è davvero molto veloce. Grazie. – PaulH
Si dovrebbe leggere la risposta di Matthieu M., è molto più completa e abbastanza buona e affronta una buona parte dei problemi che si incontrano se si distribuiscono i propri allocatori. –