Ottimizzare C++/Tecniche generali di ottimizzazione/Input/Output: differenze tra le versioni
Contenuto cancellato Contenuto aggiunto
→Formato binario: osservazione |
Nessun oggetto della modifica |
||
Riga 4:
'''Per eseguire operazioni di input/output, invece di usare le primitive del linguaggio, usa direttamente le chiamate al sistema operativo.'''
Le primitive di I/O dei linguaggi di programmazione sono pensate soprattutto tenendo conto della comodità
Tuttavia, a volte si vuole ottimizzare anche il codice eseguito per effettuare operazioni di I/O. Inoltre, nel caso del C++, la libreria degli stream è particolarmente inefficiente. Le chiamate al sistema operativo garantiscono la massima efficienza, a costo di rinunciare alla portabilità ad altri sistemi operativi, e di dover gestire manualmente la formattazione, la bufferizzazione, e gli errori. === Formato binario ===
'''Invece di memorizzare i dati su file in modalità testuale, memorizzali in formato binario.'''
I numeri in formato binario occupano mediamente meno spazio, e quindi richiedono meno tempo per essere letti da disco e scritti su disco, ma, soprattutto, scrivendo e leggendo i dati nello stesso formato che hanno in memoria non
Lo svantaggio è che i file così ottenuti non sono ''human-readable'' e possono essere dipendenti dall'architettura del processore, ma se non c'è la necessità
=== Memory-mapped-file ===
'''Eccetto che in una sezione critica di un sistema real-time, se devi accedere a gran parte di un file binario in modo non-sequenziale, invece di accedervi ripetutamente con operazioni di ''seek'', oppure di caricarlo tutto in un buffer dell’applicazione, usa un [[w:en:Memory-mapped file|memory-mapped-file]], se il tuo sistema operativo fornisce tale strumento.'''
Quando si deve accedere a gran parte di un file binario in modo non-sequenziale, ci sono due tecniche alternative standard:
Line 20 ⟶ 24:
* Allocare un buffer grande quanto tutto il file, aprire il file, leggere tutto il contenuto del file nel buffer, chiudere il file; e ogni volta che si deve leggere un dato, cercarlo nel buffer.
Rispetto alla prima tecnica, usando i memory-mapped-file
Rispetto alla tecnica di precaricare in memoria l'intero file, usando i memory-mapped-file
* Usando le primitive di lettura di file, i dati vengono normalmente letti prima nella cache del disco e poi nella memoria del processo, mentre con i memory-mapped-file si accede direttamente al buffer caricato dal disco, risparmiando così sia un'operazione di copia che lo spazio di memoria per la cache del disco. Analoga situazione si ha per la scrittura su disco.
* Leggendo tutto il file, il programma si blocca per un tempo significativo per leggere il file, mentre usando un memory-mapped-file tale tempo viene distribuito nel corso dell'elaborazione, man mano che si accede alle varie parti del file.
Line 31 ⟶ 35:
Tuttavia, l’uso di memory mapped file non è appropriato in una porzione critica di un sistema real-time, in quanto l'accesso a tali dati ha una latenza fortemente variabile a seconda che il dato acceduto sia in cache o su disco.
A rigore, questa è una tecnica dipendente dalla piattaforma, in quanto la funzionalità dei memory
Tuttavia, dato che tale funzionalità esiste in tutti i principali sistemi operativi dotati di memoria virtuale, questa tecnica si può considerare di ampia applicabilità. Ecco una classe che incapsula le primitive di accesso in sola lettura a un file tramite memory-mapped-file, utilizzabile sia nei sistemi operativi di tipo Posix (come Unix, Linux, e Mac OS X), sia in ambiente Microsoft Windows, seguita da un piccolo programma che dimostra l'uso di tale classe.
'''File "memory_file.hpp":'''
Line 147 ⟶ 152:
[[Categoria:Ottimizzare C++|Input/Output]]
{{Avanzamento|
|