Ho un'applicazione C++ in cui talvolta richiede un grande buffer di tipi POD (ad esempio un array di 25 b illion float
s) da tenere in memoria in una volta in un blocco contiguo. Questa particolare organizzazione della memoria è guidata dal fatto che l'applicazione utilizza alcune API C che operano sui dati. Pertanto, una disposizione diversa (come un elenco di pezzi più piccoli di memoria come gli usi std::deque
) non è fattibile.È possibile liberare parzialmente la memoria allocata dinamicamente su un sistema POSIX?
L'applicazione ha un algoritmo che viene eseguito sull'array in modalità streaming; pensare qualcosa di simile:
std::vector<float> buf(<very_large_size>);
for (size_t i = 0; i < buf.size(); ++i) do_algorithm(buf[i]);
Questo particolare algoritmo è la conclusione di una pipeline di fasi di lavorazione precedenti che sono state applicate al dataset. Pertanto, una volta che il mio algoritmo ha passato l'elemento i
-th nella matrice, l'applicazione non ne ha più bisogno.
In teoria, quindi, ho potuto liberare quella memoria per ridurre l'ingombro di memoria della mia applicazione mentre masticava i dati. Tuttavia, fare qualcosa di simile a un realloc()
(o a std::vector<T>::shrink_to_fit()
) sarebbe inefficiente perché la mia applicazione avrebbe dovuto passare il suo tempo a copiare i dati non utilizzati nel nuovo spot in fase di riallocazione.
La mia applicazione funziona su sistemi operativi conformi a POSIX (ad esempio Linux, OS X). C'è un'interfaccia con la quale potrei chiedere al sistema operativo di liberare solo una regione specifica dalla parte anteriore del blocco di memoria? Questo sembrerebbe essere l'approccio più efficiente, in quanto potevo semplicemente notificare al gestore della memoria che, ad esempio, i primi 2 GB del blocco di memoria possono essere recuperati una volta che ho finito con esso.
Alloca tutta la memoria in una volta all'inizio? Se sì: è necessario? Se no: hai provato i ringbuffer? – Gombat
sì, un buffer circolare è ciò di cui hai bisogno. –
@Gombat: avrei dovuto inserire questo dettaglio nell'OP, ma un passaggio precedente della catena di elaborazione richiede che l'intero buffer sia in memoria (come un blocco contiguo, quando viene passato a un'API C) in una volta. Altrimenti sì, un buffer circolare sarebbe sicuramente la scelta giusta. L'algoritmo a cui mi riferisco nella domanda è la conclusione di una pipeline di più fasi di elaborazione; una volta terminato, non ho più bisogno dei dati. –