Ho implementato gli allocatori di Andrei Alexandrescu come esercizio, ma mi sono bloccato sul suo Freelist
. Il% co_de di Andrei è simile al seguente:
template<class BaseAllocator,
std::size_t kMinSize,
std::size_t kMaxSize /* Actual size of each block on the freelist */,
std::size_t kBatchSize,
std::size_t kMaxRemembered>
class Freelist
{
// ...
};
Tutto tranne il Freelist
ha un'implementazione chiara per me. Facciamo un esempio specifico:
Freelist<A, 8, 8, 8, someLargeNumber>
In sostanza, una freelist che memorizza blocchi di dimensioni kBatchSize
nel suo elenco, ma alloca 8
byte dall'allocatore principale quando viene richiesto di allocare 8*8=64
, inserendo i byte rimanenti nella lista dei risultati.
Alcuni dei miei pensieri su come implementare questo sono i seguenti (supponiamo che 8
sia il numero di blocchi sull'elencare):
- Unisciti ai blocchi di memoria adiacenti quando aggiungi blocchi gratuiti alla lista dei preferiti. Questo perde la complessità di
n
che avevamo in precedenza, e ha anche il problema che è possibile unire blocchi che provengono effettivamente da allocazioni differenti. - Potrei modificare la tecnica precedente per allocare sempre la memoria allineata alla dimensione del batch. Quindi, potrei usare l'allineamento per determinare se due blocchi provengono da allocazioni differenti. Questo ha ancora il problema di complessità e limita
O(1)
ekMaxSize
a potenze di due (come l'allineamento deve essere una potenza di due) - Potrei avere un
kBatchSize
per memorizzare ulteriori informazioni su un determinato batch. Non mi piace questa idea perché modifica il requisito di memoria dastd::vector<Batch, BaseAllocator>
aO(1)
. I liberi professionisti senza allocazione batch possono essere implementati in quasi nessuna memoria aggiuntiva (un puntatore all'inizio e forse una dimensione dell'elenco) - Potrei richiedere
O(n)
per essere ciò che chiamerei un "allocatore segmentabile"; cioè, i segmenti di un blocco possono essere deallocati separatamente, o uniti e deallocati insieme. Sebbene ciò renderebbe insignificante l'implementazione diBaseAllocator
, questo sembra un requisito troppo grande da inserire inFreelist
Nessuno di questi approcci mi sembra giusto. Se l'allocazione in lotti è una valida ottimizzazione per un elenco a dominio libero, sembra che dovrebbe esserci un modo per implementarlo in BaseAllocator
di spazio e tempo.