2009-11-15 19 views
31

Ho creato due programmi, uno con malloc e l'altro con mmap. Il tempo di esecuzione utilizzando mmap è molto inferiore all'utilizzo di malloc.malloc vs mmap in C

So ad esempio che quando si utilizza mmap si evita di leggere/scrivere chiamate sul sistema. E l'accesso alla memoria è inferiore.

Ma ci sono altri motivi per i vantaggi quando si utilizza mmap su malloc?

Grazie mille

+0

Posso supporre che il tuo programma malloc utilizzi read/write o fread/fwrite per fare un po 'di I/O sul file che hai mmap nell'altro caso? – Suppressingfire

+0

Sì, in realtà sto utilizzando lettura/scrittura con malloc, mmap e l'utilizzo delle normali chiamate R/W. utilizzando le chiamate R/W è più veloce rispetto all'utilizzo di malloc, suppongo sia perché l'accesso al disco è più veloce della memoria. – Peter

+6

Non è che l'accesso al disco sia più veloce della memoria. Quasi sempre, la memoria è molto più veloce del disco e malloc non è ciò che costa tempo. Il codice mmap è più veloce perché per il tuo programma, mmap ha comportato un minore accesso al disco o un accesso al disco più efficiente rispetto a qualsiasi altra lettura o scrittura confrontata. Ad esempio, "scriver" l'intero file invia effettivamente tutti quei byte su disco. mmap significa semplicemente * se * si modificano i dati di 'mmap', * quindi * il sistema operativo scriverà le modifiche. Quindi se finisci per non modificare l'intero file, potresti sempre scriverne solo una parte. –

risposta

11

Presumo che ci si riferisce a utilizzare mmap e malloc per la lettura dei dati da file. In questo caso hai praticamente il punto principale:

  • utilizzando fread/fwrite devi fare molte chiamate al sistema operativo.
  • utilizzando mmap sembra di avere accesso all'intero file in un'unica operazione. Questo non è completamente vero perché il sistema operativo probabilmente esegue il mapping del file uno memory page alla volta, ma è ancora molto più veloce.
+1

Per aggiungere a questo, 'fread' è buffered questo significa che se è preceduto da un fseek riempirà sempre il suo buffer completamente. Avevo un programma che legge un file in sequenza ma che precede un 'fseek' prima di ogni record (di dimensione 32) che legge 8192 byte.Quindi ha finito con la lettura di 256 volte più dati del necessario, oltre a leggere sempre due chiamate al kernel. Con 'mmap' non ne hai (visibile). –

7

mmap non carica effettivamente il file in memoria, quindi verrà caricato più velocemente, ma la modifica sarà più lenta.

Un altro punto è che mmap non utilizza alcuna memoria, ma occupa spazio di indirizzamento. Su una macchina a 64 bit, la maggior parte dello spazio di indirizzamento della memoria non avrà memoria, quindi è possibile caricare file enormi, ad esempio 5 GB, che non si vorrebbe malloc.

0

mmap in realtà non legge il file. Lo mappa semplicemente per indirizzare lo spazio. Ecco perché è così veloce, non ci sono I/O su disco fino a quando non si accede effettivamente a quella regione di spazio degli indirizzi.

malloc è semplicemente una mappatura di spazio di indirizzi alla memoria

6

gente guarda, contrariamente a quanto si crede, mmap è davvero una funzione di allocazione di memoria simile a malloc ..

il file mmaped è uno uso di esso .. si può usare come funzione di allocazione della memoria che passa -1 come descrittore di file ..

così .. l'uso comune è quello di utilizzare malloc per gli oggetti piccoli e mmap per i più grandi ..

questo è un buon strategia ..

i usano alloca() per per l'ambito funzione solo variabili ..

+5

Normalmente l'allocatore userà 'mmap' stesso a seconda delle dimensioni dell'area richiesta con' malloc'. Su Solaris quando si richiedono più di 128K si ottiene un blocco mappato in memoria 'MAP_ANON'. Su OS/X il limite è 64K se ricordo male, altri sistemi e librerie di allocazione avranno altri valori. –

8

Sia malloc e mmap sono lento a volte. Dipende principalmente dal modello di utilizzo:

mmap: Il sottosistema di paging del kernel funziona in unità di dimensioni di pagina. Questo significa che se vuoi leggere un'intera pagina da un file e vuoi farlo ripetutamente (buona localizzazione), con MMAP andrà bene. Contrariamente, se si mappa quel file da 5 Gb e si fa accesso sparsi, si avrà il kernel che scambia le pagine dentro e fuori molto. Oltre all'effettivo I/O, la gestione della pagina richiederà del tempo. Se si hanno dubbi sulla latenza, evitare questo modello di accesso, poiché il meccanismo di recupero della pagina Linux tende ad essere instabile e causerà ritardi evidenti e l'avvelenamento della cache rallenterà altri processi.

malloc: Va bene quando è necessario memoria che non è in unità di dimensione della pagina. ma non puoi fare cose come mlock() saggiamente. In termini di I/O, la velocità dipende molto da come lo fai. fread/fwrite può mappare le pagine dietro le quinte o farà il buffering nello userspace. L'accesso localizzato sarà piuttosto veloce. lettura/scrittura passano direttamente attraverso il kernel, così piccoli accessi distribuiti causeranno ancora I/O a causa di errori di cache, ma i dati effettivi trasferiti da kernel-> userspace saranno leggermente inferiori. Non so se questo è misurabile.

A meno che mlock() non sia stato modificato, le pagine utente possono essere scambiate/riscritte in qualsiasi momento. Anche questo richiede tempo. Quindi su sistemi con poca memoria, vincerà la variante che mappa la minor quantità di memoria. Con il kernel Linux, ogni sistema ha una memoria insufficiente poiché le pagine non utilizzate vengono utilizzate per la cache di I/O e il kernel potrebbe impiegare tempo notevole per renderle disponibili se l'utilizzo della memoria o l'I/O sono scoppiettanti.

-3

Per mmap RAM non è concesso. Lo spazio indirizzo è concesso.

Quando si accede allo spazio di indirizzi, si verifica un errore di pagina. Durante l'errore di pagina nella dimensione della pagina, in genere 4096 byte, viene fornita la RAM .

Anche il contenuto di RAM è fornito. Se da un file viene supportato lo spazio indirizzo apparirà il contenuto del file. Se per MAP_ANONYMOUS viene eseguito il backup dello spazio indirizzo , viene visualizzata la RAM inizializzata a zero.

Con i due precedenti sono descritti. Innanzitutto, è possibile inizializzare esattamente la RAM desiderata. Secondo, fino a quando non viene fornita la RAM richiesta.

Per una richiesta di indirizzo inferiore a 2 megabyte da malloc viene estesa l'interruzione di programma. Mentre gli indirizzi vicini all'interruzione del programma vengono forniti , l'interruzione di programma non può essere interrotta. Pertanto, la RAM liberata dal kernel potrebbe non essere restituita. Segue un'analogia. Le calze possono essere rimosse prima delle scarpe?

Con l'invocazione di munmap nel kernel, la RAM viene immediatamente restituita. Con mmap e munmap la probabilità di swap viene mitigata. La probabilità di swap di espansione del programma di malloc viene incitata.

Con malloc inferiore alla dimensione della pagina, è possibile allocare memoria. La memoria discontinua diventa. La memoria del kernel può anche frammentare. Nessuno dei due è perfetto.

Su qualsiasi processore inattivo da parte del kernel, la RAM può essere sbrigliata. Vengono create pagine enormi trasparenti di 2 megabyte. Rispetto a 512 errori di pagina per fornire 2M Quando da un singolo errore di pagina 2M può essere fornito diventa un vantaggio di prestazioni significativo.

Per mmap esiste almeno un alone notevole. Per il backing di mmap è possibile utilizzare un descrittore di file pipe. Un errore non diventa. Tuttavia, nell'indirizzo di memoria i dati forniti dal tubo non vengono visualizzati.

Tuttavia, se MAP_ANONYMOUS viene utilizzato quindi dal descrittore di file pipe nell'indirizzo fornito da mmap, i dati possono essere letti. Anche se non è così efficiente, il risultato desiderato diventa. Da un lseek fallito return e errno è possibile identificare un descrittore di file collegato alla pipa.

Da computer che possono indirizzare un intero megabyte e eseguire un sistema operativo basato su disco quindi l'uso di malloc è essenziale. Se si utilizza la libreria C fornita la funzione getline , sarà probabilmente utilizzato malloc e free.

Su un sistema operativo controllato da kernel invece di mmap perché utilizzare malloc? Rispetto a malloc; mmap sembra complicato? Per invocare munmap deve essere fornito anche l'importo dello spazio di indirizzo richiesto in precedenza . l'uso di malloc è più portatile? malloc sembra più conveniente?

Tuttavia, se si desidera ottenere prestazioni, viene utilizzato mmap.

Ultimo, ma non meno importante, se MAP_SHARED quindi con i processi di progenie i dati possono essere condivisi. Evitare i pthreads è fondamentale. A volte il clone può anche essere evitato.

Sebbene personale, metodi di allocazione variabile elencate in più al meno preferito segue: registro/pila; mmap; globale; malloc. A mano a mano che diversi divieti e divieti diventano. Da un programma sufficientemente complicato; vengono utilizzati tre o forse tutti e quattro i metodi.

+2

Questa risposta ha bisogno di qualche modifica seria. –

+2

Nay matey, È solo bisogno di 'pirate speakin' per essere makin 'correctus in yer headin'. –