2010-01-03 20 views
8

Ho un programma che legge i dati da 2 file di testo e quindi salvare il risultato in un altro file file. Dato che ci sono molti dati da leggere e scrivere che causano un successo nelle prestazioni, voglio parallelizzare le operazioni di lettura e scrittura.Come parallelizzare la lettura e la scrittura

Il mio primo pensiero è, utilizzare 2 fili come un esempio, un thread di lettura/scrittura fin dall'inizio, e un altro thread di lettura/scrittura a partire dalla metà del file. Poiché i miei file sono formattati come linee, non come byte (ogni riga può avere diversi byte di dati), la ricerca per byte non funziona per me. E la soluzione che potrei pensare è usare getline() per saltare prima le righe precedenti, il che potrebbe non essere efficiente.

C'è un buon modo per cercare di una linea specificata in un file? o hai altre idee per mettere in parallelo la lettura e la scrittura di file?

Ambiente: Win32, C++, NTFS, singolo disco rigido

Grazie.

-Dbger

+1

qual è il tuo filesystem e quale hardware usi? se si dispone di un solo controller/disk, potrebbe non essere efficace per farlo I paralleli/O – Anycorn

+0

è così che significa parallize disco I/O sarà sempre causare un degrado delle prestazioni se solo lettura/scrittura sullo stesso disco? –

+1

Dbger: se si utilizza un disco rigido, sì. – Mike

risposta

18

In generale, NON si vuole per parallelizzare disco I/O. I dischi rigidi non amano l'I/O casuale perché devono continuamente cercare in giro per arrivare ai dati. Supponendo che non si stia utilizzando RAID e che si stiano utilizzando dischi rigidi anziché una memoria allo stato solido, si riscontrerà un grave peggioramento delle prestazioni se si parallelizza l'I/O (anche quando si utilizzano tecnologie come queste, è ancora possibile vedere alcune prestazioni degrado quando si eseguono molti I/O casuali).

Per rispondere alla tua seconda domanda, non c'è davvero un buon modo per cercare di una certa riga in un file; si può solo cercare in modo esplicito ad un offset usando la funzione read byte (vedi this page per maggiori dettagli su come usarlo.

+0

Quindi in lettura/scrittura di file, la ricerca di dischi costa la maggior parte del tempo, come nel caso di ambiente multi-threading, giusto? –

+2

Sì, il tempo di ricerca del disco sarà generalmente il collo di bottiglia è un ambiente I/O con multithreading. Dovresti provare a serializzare l'I/O laddove possibile. – Mike

+0

Grazie Mike, solo per confermare, questo si applica solo quando leggi un singolo file, o si applica anche quando leggi più file (thread 1 leggi file1, thread2 leggi file2) –

1

Questo non è davvero una risposta alla tua domanda, ma piuttosto un re-design (che tutti noi l'odio ma non posso fare nulla) Come già accennato, cercare di accelerare I/O su un disco rigido con più thread probabilmente non sarà di aiuto

Tuttavia, potrebbe essere possibile utilizzare un altro approccio a seconda della sensibilità dei dati , esigenze di throughput, dimensioni dei dati, ecc. Non sarebbe difficile creare una struttura in memoria che mantenga un'immagine dei dati e consenta aggiornamenti facili e veloci delle righe di testo in qualsiasi punto dei dati. Potresti quindi utilizzare una discussione dedicata che controlla semplicemente quella struttura e il cui compito è scrivere i dati sul disco. Scrivere i dati sequenzialmente su disco può essere estremamente veloce; può essere molto più veloce che cercare casualmente in sezioni diverse e scriverlo a pezzi.

+0

Quando scrivo dei dati 2M in un file di testo, sequenzialmente, costa circa 1 secondo sulla mia macchina, che è troppo lento per me. Come per leggere, al fine di formare una struttura di memoria del file, ho bisogno di leggere i dati in primo luogo, che è anche troppo lento per soddisfare la mia esigenza. Tuttavia, vorrei esaminare gli argomenti su I/O sovrapposti e file Memorymap per vedere se questo aiuta. –

+1

1 secondo per scrivere 2 MB? Sembra incredibilmente lento. Ho appena eseguito un test che scrive 10M in un file in circa 100ms e il mio PC non è un vero speed machine (3.2GHz e I * think * 7200rpm drive). Con quali API stai usando per aprire e scrivere sul file? –

+0

Sto usando std :: ofstream per salvare molti dati separati in un ciclo. come "per (...) {streamOut << x; streamOut << y}", e ho anche un disco da 7200rpm con CPU dual core da 2.16GHz –

2

Queuing più letture e le scritture non aiuterà quando si sta eseguendo contro un disco. Se la tua app ha anche lavorato molto sulla CPU, potresti fare letture e scritture in modo asincrono e lasciare che la CPU funzioni mentre l'I/O del disco viene eseguito in background. In alternativa, prendi un secondo disco rigido fisico: leggi da uno, scrivi all'altro. Per insiemi di dati di dimensioni modeste che sono spesso efficaci e un po 'più economici rispetto alla scrittura di codice.

+0

Utilizzare un thread di sfondo per scrivere gradualmente i dati di output quando la CPU è occupata con il calcolo, è una buona idea. Ma come leggere, non c'è molto lavoro da fare dato che i dati non sono pronti. –

+0

Dbger, dipende dalla natura dei tuoi dati. Se sei in grado di accodare un secondo recupero asincrono per essere soddisfatto durante l'elaborazione dei dati del primo recupero in cui ti trovi. Di nuovo, è più efficace se il disco non è occupato con altri I/O, quindi probabilmente non è applicabile alla tua situazione immediata. –

Problemi correlati