2012-02-26 12 views
7

Ho un enorme file di testo separato dalla linea e voglio fare alcuni calcoli su ogni riga. Ho bisogno di fare un programma multithread per processarlo perché è l'elaborazione di ogni linea che impiega più tempo per completare piuttosto che leggere ogni riga. (Il collo di bottiglia sta nella elaborazione della CPU, piuttosto che il IO)Accesso Muti-threaded allo stesso file di testo

Ci sono due opzioni mi si avvicinò con:

1) aprire il file dal thread principale, creare un blocco sul file handle e passare i gestire tutti i thread di lavoro e consentire a ciascun lavoratore di accedere direttamente al file direttamente

2) Creare un'impostazione di produttore/utente in cui solo il thread principale ha accesso diretto al file e alimenta le righe per ogni thread di lavoro utilizzando una coda condivisa

Cose da sapere:

  • Sono molto interessato a prestazioni di velocità per questo compito
  • Ogni linea è indipendente
  • sto lavorando questo in C++, ma credo che il problema qui è un po 'indipendente dal linguaggio

Quale opzione sceglieresti e perché?

+0

quanti processori userete e quanto è grande il file? – amit

+0

il file è di circa 20 GB e in futuro le implementazioni saranno ancora più grandi. Attualmente sto lavorando su 4 core – Alexandros

+1

@Alexandros: so che sono in ritardo per rispondere :). Ma non assegnare un blocco di linee a ciascun thread è molto più semplice? È possibile calcolare in anticipo il blocco per ogni thread utilizzando un puntatore a file singolo e in seguito ogni thread apre il file e cerca la posizione calcolata in precedenza. Penso che questo approccio sarà più facile e veloce – Arunmu

risposta

5

Vorrei suggerire la seconda opzione, dal momento che sarà più chiara la progettazione e meno complicata della prima opzione. La prima opzione è meno scalabile e richiede ulteriori comunicazioni tra thread per sincronizzare lo stato di avanzamento sulle righe del file. Mentre nella seconda opzione hai un dispatcher che si occupa dell'IO e avvia i thread dei lavoratori per iniziare il calcolo, e ogni thread di calcolo è completamente indipendente l'uno dall'altro, quindi ti consente di ridimensionare. Inoltre nella seconda opzione separa la tua logica in modo più chiaro.

+0

+1 per la coda P-C. Suggerirei una classe per le comunicazioni tra thread che buffer un numero utile di righe in modo che ogni thread di elaborazione passi la maggior parte del tempo effettivamente in elaborazione. Vorrei controllare il flusso di questo sistema creando un pool di questi oggetti di buffer di linea all'avvio (cioè un'altra coda P-C caricata con essi). –

0

Se ogni riga è veramente indipendente e l'elaborazione è molto più lenta della lettura del file, è possibile leggere tutti i dati contemporaneamente e archiviarli in una matrice, in modo che ogni riga rappresenti l'elemento di una matrice.

Quindi tutti i thread possono eseguire l'elaborazione in parallelo. Ad esempio, se si dispone di 200 righe e 4 thread, ogni thread potrebbe eseguire il calcolo su 50 righe. Morever, dal momento che questo metodo sarebbe imbarazzantemente parallelo, si potrebbe facilmente usare OpenMP per questo.

+0

sfortunatamente il file è troppo grande per adattarsi alla memoria – Alexandros

+1

Quindi penso che la seconda opzione sia buona, in cui il thread principale legge grandi blocchi di dati e li invia ai thread worker. – MetallicPriest

1

Se stiamo parlando di file di grandi dimensioni, che devono essere elaborati con un cluster di grandi dimensioni - MapReduce è probabilmente la soluzione migliore.

Il framework consente una grande scalabilità e gestisce già tutto il lavoro sporco di gestione degli operatori e tollerando i guasti per voi.
Il framework è specificamente progettato per ricevere i file letti dal file system [originariamente per GFS] come input.

Si noti che non v'è un'implementazione open source di mappa-riducono: Apache Hadoop

+1

Non è necessario il caso giusto per utilizzare MapReduce. Cosa succede se nel suo caso non esiste una nozione di riduzione effettiva? –

+0

@ArtemBarger: map-reduce viene spesso utilizzato con la funzione Identity come passo di riduzione. Un buon esempio è l'ordinamento basato sulla riduzione della mappa. – amit

+0

Lo so, ma la domanda era, e se Alexandros usa il caso non si adatta a questa nozione. –

0

Vorrei suggerire la seconda opzione perché è sicuramente meglio di design-saggio e permetterebbe di avere un migliore controllo del lavoro che il lavoratore le discussioni stanno facendo

inoltre che aumenterebbe le prestazioni in quanto la comunicazione inter-thread in questo caso è il minimo delle due opzioni descritte

+0

Da quando la copia-passato delle risposte precedenti viene conteggiata come risposta corretta? –

+0

Mi dispiace, non l'ho visto nell'ordine corretto, l'ho risolto – Alexandros

+2

@ArtemBarger Non ho visto la tua risposta prima di aver postato il mio, ho semplicemente scritto a mio avviso mentre stavo lavorando su altro, quindi era un po 'lento. L'OP ha fatto bene ad accettare la tua risposta come più completa, più veloce e generalmente migliore, ma non c'è motivo di accusare le persone di incollare o di fare downvoting per quell'unica ragione – Lefteris

0

Un'altra opzione è quella di memoria mappa il file e mantenere una struttura comune movimentazione mutua esclusione correttamente i fili.

Problemi correlati