Perché std :: gli allocatori non sono così popolari? [chiuso]

8

Con le ultime tendenze sulle applicazioni C e C ++, e con l'ultimo intendo gli ultimi anni, mi aspettavo di vedere std::allocator s da utilizzare più frequentemente di quello che è realmente.

Le applicazioni moderne sono generalmente multithread o con una forma di concorrenza e gestiscono una quantità significativa di memoria, specialmente in alcuni campi come giochi e applicazioni multimediali; quindi il solito costo elevato delle allocazioni / deallocazioni aumenta e incide sulle prestazioni ancor più che nelle vecchie applicazioni.

Ma per quello che posso vedere questo tipo di gestione della memoria attraverso std::allocator s non è popolare, non posso nemmeno contare 1 libreria che conosco, che sta usando qualsiasi logica per un modo standard per gestire la memoria.

C'è una vera ragione per cui std::allocator non è popolare? Motivi tecnici?

    
posta user2485710 06.05.2014 - 03:05
fonte

3 risposte

10

Qui ci sono due domande:

1) Perché std::allocator non è più utilizzato?

La risposta breve è perché per la maggior parte degli usi è sufficiente usare new e delete .

In primo luogo, una breve panoramica di ciò a cui è destinato il concetto di C ++ 11 Allocator. Fondamentalmente, quando si esegue un new Foo , entrambi allocano memoria e quindi costruiscono l'oggetto in quella memoria.

Ma se fosse necessario allocare memoria e costruire come due passaggi separati. Il classico esempio di questo è std::vector , che può allocare memoria senza inizializzarlo immediatamente, ma poi costruisce gli elementi man mano che li aggiungi al contenitore. Il punto di std::allocator è di fornire un'interfaccia per eseguire questi passaggi separati in modo uniforme.

Tuttavia, per la maggior parte degli utenti, non hanno bisogno di quel livello di controllo, perché è solo un'altra cosa da ricordare quando si puliscono le eccezioni.

2) Perché non più cose fanno uso del concetto di C ++ di Allocator ?

Per lo più non c'è bisogno. Le uniche classi che tendono a usarle sono quelle che vogliono dare ai propri utenti un maggiore controllo sull'origine della memoria che allocano. I contenitori della libreria Standard sono scritti in questo modo in modo che l'utente possa prendere tali decisioni se lo desiderano, ma utilizzano in genere l'allocatore normale.

    
risposta data 06.05.2014 - 03:32
fonte
4

La popolarità di un linguaggio o di un concetto di biblioteca è in una correlazione inversa con la sua complessità di fondo.

Il std::allocator è un concetto di basso livello e in quanto tale presenta potenziali insidie. Avere un allocatore personalizzato in anticipo è probabile che venga giudicato un'ottimizzazione prematura. Inoltre, analogamente ad altri concetti di basso livello, è generalmente preferito delegare la gestione dell'allocazione del lavoro alle librerie (stdlib, boost) a meno che il sovraccarico di gestione della complessità delle proprie allocazioni sia assolutamente giustificato.

Considera gli indicatori come solo un esempio di supporto di questa tesi. Amiamo i puntatori per il loro accesso impreparato alla memoria e zero overhead, ma in C ++ sappiamo usare meglio i wrapper scoped / raii per gestire la complessità, fino a quando non avremo bisogno esplicitamente delle prestazioni o possiamo essere d'accordo su alcune semantiche non proprietarie per certe casi d'uso ben definiti.

Quando usi uno std :: allocator devi considerare l'ABI e le compatibilità API, e una domanda meravigliosa come il comportamento desiderato quando il codice è coinvolgente
std::vector<T,A1>().swap(std::vector<T,A2>()) con differenti (e stateful!) A1 e A2 allocatori. Inoltre, alcuni contenitori non usano nemmeno l'allocatore nel modo desiderato! Guarda ad esempio std::list<T,A> o std::map<K,T,C,A> . L'aspettativa naturale è che l'allocatore venga utilizzato per allocare oggetti di tipo T per un elenco o pair<const K,T> per una mappa, ma in pratica un'implementazione di una libreria standard richiederà di allocare un elenco o un nodo di mappa, e anche il la dimensione del nodo può essere diversa tra le versioni di rilascio e di debug. Gli allocatori personalizzati sono pieni di minuzie e la complessità e i dettagli aggiuntivi non sono necessari per le attività di programmazione più comuni.

    
risposta data 06.05.2014 - 11:32
fonte
2

Un allocatore è un criterio inserito dalla dipendenza, nei contenitori standard. È lì soprattutto per consentire al codice client di separare la politica di allocazione dall'istanza, nei contenitori già implementati .

Il problema si presenta quando devi usare std :: containers, e il criterio di allocazione predefinito (come implementato da std :: allocator) non soddisfa i bisogni del tuo progetto (es. vuoi che l'implementazione di std :: vector lancia se sono allocati più di 1024 oggetti, si desidera utilizzare un pool di memoria o assicurarsi che tutte le allocazioni siano preallocate in una determinata area di memoria e così via).

Se non potessi iniettare un diverso allocatore nei contenitori, questo ti proibirebbe di usare std :: containers alltogether in alcuni progetti.

Per aggirare questo problema (e assicurarsi di poter ancora usare std :: container quando si hanno requisiti di memoria complessi), l'allocatore è un parametro basato sui modelli per i contenitori.

Per rispondere alla tua domanda : la maggior parte delle persone non usa std :: allocators perché quando scrivono il codice client hanno il pieno controllo delle allocazioni - quindi non hanno bisogno di iniettare una politica di allocazione - e quando usano il codice della libreria, lo std :: allocator di solito è sufficiente.

    
risposta data 06.05.2014 - 10:54
fonte

Leggi altre domande sui tag