Sto usando la funzione di I/O di basso livello 'write' per scrivere alcuni dati su disco nel mio codice (linguaggio C su Linux). Innanzitutto, accumulo i dati in un buffer di memoria, quindi utilizzo 'write' per scrivere i dati sul disco quando il buffer è pieno. Quindi qual è la dimensione del buffer migliore per "scrivere"? Secondo i miei test non è tanto più veloce, quindi sono qui per cercare la risposta.qual è la dimensione del buffer corretta per la funzione 'scrivi'?
risposta
Probabilmente vi sono alcuni vantaggi nell'effettuare scritture che sono multipli della dimensione del blocco del filesystem, specialmente se si sta aggiornando un file sul posto. Se scrivi meno di un blocco parziale in un file, il sistema operativo deve leggere il vecchio blocco, combinare i nuovi contenuti e quindi scriverlo. Ciò non accade necessariamente se si scrivono rapidamente piccoli pezzi in sequenza perché gli aggiornamenti verranno eseguiti sui buffer in memoria che verranno scaricati successivamente. Tuttavia, una volta ogni tanto si potrebbe innescare qualche inefficienza se non si sta compilando un blocco (e uno allineato correttamente: più dimensioni del blocco con un offset che è un multiplo della dimensione del blocco) con ciascuna operazione di scrittura.
Questo problema delle dimensioni del trasferimento non va necessariamente a finire con mmap. Se si mappa un file e quindi memcpy
alcuni dati nella mappa, si sta creando una pagina sporca. Quella pagina deve essere svuotata in un secondo momento: è indeterminata quando. Se fai un altro memcpy
che tocca la stessa pagina, quella pagina potrebbe essere pulita ora e la stai rendendo nuovamente sporca. Quindi viene scritto due volte. Le copie allineate alla pagina dei multipli, di una dimensione della pagina, saranno la strada da percorrere.
Si vorrà che sia un multiplo della dimensione della pagina della CPU, in modo da utilizzare la memoria nel modo più efficiente possibile.
Ma idealmente si preferisce utilizzare mmap, in modo che non si debba mai occuparsi dei buffer da soli.
+1 per l'utilizzo di mmap –
Quindi, se si desidera scrivere 3 GB di dati, è possibile creare un mmap da 3 GB? Haha. Potresti fare un mmap più piccolo e poi rimapparlo mentre avanzi nel file, il che è più complicato. Per quanto riguarda i buffer: beh, qual è il mmap? È una regione di memoria con un puntatore di base e un puntatore corrente che ti dice dove memorizzare il prossimo pezzo. E qual è la dimensione ideale per quelle operazioni memcpy? Se copi 300 byte qui, 300 byte lì, potresti attivare scarichi sub-ottimali. Cioè la CPU potrebbe prenderti mentre crei la stessa pagina sporca due volte e sciacquala due volte. – Kaz
cosa succede se i dati da elaborare sono molto più grandi della RAM? –
Dipende dalla quantità di RAM, VM, ecc. Nonché dalla quantità di dati da scrivere. La risposta più generale è quella di valutare quale buffer funzioni meglio per il carico con cui si ha a che fare e utilizzare ciò che funziona meglio.
Si potrebbe utilizzare BUFSIZ
definita <stdio.h>
Altrimenti, utilizzare un piccolo multiplo della dimensione pagina sysconf(_SC_PAGESIZE)
(ad esempio due volte tale valore). La maggior parte dei sistemi Linux ha pagine da 4Kbyte (che è spesso uguale o un piccolo multiplo della dimensione del blocco del filesystem).
Come altri ha risposto, utilizzando la chiamata di sistema mmap(2) potrebbe aiutare. I sistemi GNU (ad esempio Linux) hanno un'estensione: la seconda stringa di modalità di fopen può contenere l'ultimo m
e quando ciò accade, la libc GNU tenta di mmap
.
Se si trattano dati di dimensioni quasi pari alla RAM (o metà), è possibile anche utilizzare madvise(2) per ottimizzare le prestazioni di mmap
.
Vedere anche this answer per una domanda del tutto simile alla vostra. (È possibile utilizzare 64 KB come dimensione del buffer ragionevole).
La dimensione "migliore" dipende molto dal file system sottostante.
I stat
e fstat
chiamate riempire in una struttura dati, struct stat
, che comprende i seguenti campi:
blksize_t st_blksize; /* blocksize for file system I/O */
Il sistema operativo è responsabile per il riempimento di questo campo con un "buona dimensione" per) blocchi (scrittura.Tuttavia, è anche importante chiamare write() con memoria "ben allineata" (ad es. Il risultato delle chiamate malloc
). Il modo più semplice per farlo è utilizzare l'interfaccia di streaming <stdio.h>
fornita (con gli oggetti FILE *
).
Utilizzando mmap
, come in altre risposte qui, può anche essere molto veloce per molti casi. Si noti che non è adatto ad alcuni tipi di flussi (ad es. Prese e pipe).
vuoi dire che fwrite è generalmente più veloce di scrivere con una dimensione buffer adeguata? –
Non necessariamente "più veloce di", ma eseguirà rapidamente copie di blocco nello spazio utente secondo necessità. Inoltre, se hai bisogno di scrivere una serie di diverse stringhe brevi da varie posizioni, le riunirà tutte insieme e passerà un blocco di dimensioni appropriate al kernel, in una chiamata di sistema. (In alcuni casi è possibile ottenere un effetto simile con 'writev', ma in genere è più di quanto valga la pena, e anche allora il kernel tende a dover fare le stesse copie di memoria.) – torek
Questo valore è destinato a essere esattamente questo, ma è risultato che se uso questo valore, è ancora più lento se ad es copiare i dati da A a B, perché devo fare più syscalls in questo modo. – glglgl
- 1. Qual è la dimensione del buffer predefinita per StreamWriter
- 2. Golang - Qual è la dimensione del buffer del canale?
- 3. Qual è la dimensione del buffer in BufferedReader?
- 4. Qual è la dimensione del pacchetto CoAP?
- 5. La schermata del simulatore iPhone non è nella dimensione corretta
- 6. Qual è la dimensione del mio Bitset?
- 7. Qual è la dimensione del vuoto?
- 8. Come trovare la dimensione del buffer del socket di linux
- 9. Qual è la corretta sintassi del bind JavaScript?
- 10. Qual è la pratica corretta del plugin jQuery?
- 11. Dimensione ottimale del buffer Android
- 12. Qual è l'icona della dimensione corretta per drawable-xxhdpi?
- 13. Qual è la dimensione del blocco del filesystem iphone?
- 14. Qual è la dimensione del carattere del titolo ActionBar predefinito?
- 15. Dimensioni ottimali del buffer per la proprietà JSP e autoflush
- 16. Come ottenere l'output completo previsto quando la dimensione del buffer interno di dimensione expect_out (buffer) supera?
- 17. Determina la dimensione corretta in loadView
- 18. Come ottenere la dimensione corretta di UITableViewCell?
- 19. Getize() di ImageFont non ottiene la dimensione corretta del testo?
- 20. dimensione buffer ottimale per la lettura di file in C
- 21. mysql: Qual è la sintassi corretta per NOT LIKE?
- 22. Qual è la codifica corretta per il tipo SNMP Unsigned32?
- 23. Qual è la terminologia corretta per le promesse javascript
- 24. Qual è la grammatica corretta per questa lingua?
- 25. Come ottenere la dimensione fisica corretta del monitor?
- 26. Dimensione del buffer ottimale per il file buffer?
- 27. La proprietà 'Estensione' testo non contiene la dimensione corretta
- 28. Come impostare la dimensione del buffer dell'encoder creata da MediaCodec
- 29. Come espandere la dimensione del buffer di input di pyserial
- 30. Modifica la dimensione del buffer di socket predefinita in Windows
+1 per fare una buona domanda ... Ho sempre voluto conoscere la dimensione giusta per la funzione di scrittura .... – aProgrammer
possibile duplicato di [Dimensione buffer ottimale per scrivere (2)] (http://stackoverflow.com/questions/8803515/optimum-buffer-size-for-write2) – Raedwald