Ottimizzare C++/Tecniche generali di ottimizzazione/Input/Output: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
Pietrodn (discussione | contributi)
→‎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à d’usod'uso invece che le prestazioni, in quanto solitamente per tale codice il collo di bottiglia non è il processore, ma la periferica.
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 c’èc'è bisogno di nessuna conversione da o verso il formato testuale.
 
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à dadi parteconsentirne delll'utenteaccesso diretto agli utenti né la necessità di leggerlicomunicarli comead altri computer che usano diverse convenzioni di solo-testoformato, si può usare tranquillamente il formato binario.
 
=== 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, ogni operazione di posizionamento viene sostituita da una semplice assegnazione a un puntatore, e ogni operazione di lettura da file viene sostituita da una semplice copia da memoria a memoria. Anche supponendo che i dati siano già nella disk cache, entrambe le operazioni effettuate con i memory-mapped-files sono notevolmente più veloci delle operazioni effettuate sui file, in quanto queste ultime comportano altrettante chiamate di libreria, le quali a loro volta effettuano chiamate di sistema.
 
Rispetto alla tecnica di precaricare in memoria l'intero file, usando i memory-mapped-file, si hanno i seguenti vantaggi:
* 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 -mapped files-file non esiste in tutti i sistemi operativi.
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|75100%|2325 maggio 2008}}