2011-09-29 13 views
8

Ho un processo a esecuzione prolungata che legge file di grandi dimensioni e scrive file di riepilogo. Per velocizzare le cose, sto elaborazione di più file contemporaneamente utilizzando normali discussioni vecchie:Threads vs Process in .NET

ThreadStart ts = new ThreadStart(Work); 
Thread t = new Thread(ts); 
t.Start(); 

Quello che ho trovato è che anche con thread separati lettura di file separate e nessun impuntamento tra di loro e con 4 thread su un 24 -core box, non riesco nemmeno a ottenere fino al 10% sulla CPU o al 10% sull'I/O del disco. Se uso più thread nella mia app, sembra che funzioni ancora più lentamente.

Direi che sto facendo qualcosa di sbagliato, ma dove è curioso è che se avvii l'intero exe una seconda e una terza volta, in realtà processa i file due o tre volte più velocemente. La mia domanda è: perché non posso ottenere 12 thread nella mia app per elaborare i dati e tassare la macchina e 4 thread in 3 istanze della mia app?

Ho profilato l'app e le funzioni più intensive e chiamate più frequentemente sono tutte chiamate di elaborazione delle stringhe.

+6

Impossibile dire senza il codice effettivo che esegue l'elaborazione del file. –

+5

Che cosa ha eseguito il profilo per dirti dove si trova il collo di bottiglia? –

+0

Ci devono essere alcuni luoghi comuni (ai quali si accede dai thread di elaborazione) con codice di blocco/sincronizzazione, potresti condividere questo codice di sincronizzazione – sll

risposta

-1

Provare a utilizzare la libreria Attività da .net 4 (System.Threading.Task). Questa libreria ha ottimizzazioni integrate per un numero diverso di processori.

ho idea di cosa è che si problema, forse perché il frammento di codice non è veramente ben informato

+0

L'uso della libreria delle attività non risolverà il problema, sta già utilizzando Thread, che quando si scava abbastanza in profondità è l'attività che verrà utilizzata da Task. –

+0

Grazie per le informazioni, cap. Volevo solo dire che la libreria delle attività ha ottimizzazioni di pianificazione e conteggio dei thread. Non è la stessa cosa che stai usando i thread grezzi. Buona giornata –

6

E 'possibile che il problema computing non è CPU bound, ma legato I/O. Non aiuta a indicare che l'I/O del disco è "solo al 10%". Non sono sicuro che questo contatore di prestazioni esista anche.

Il motivo per cui diventa più lento durante l'utilizzo di più thread è perché questi fili sono tutti cercando di raggiungere i rispettivi file allo stesso tempo, mentre il sottosistema del disco sta avendo un momento difficile cercando di soddisfare tutti i diversi thread. Vedete, anche con una tecnologia moderna come SSD in cui il tempo di ricerca è di diversi ordini di grandezza inferiore rispetto ai dischi rigidi tradizionali, c'è ancora una penalità.

Piuttosto, dovresti concludere che il tuo problema è legato al disco e un singolo thread sarà probabilmente il modo più veloce per risolvere il tuo problema.

Si potrebbe sostenere che è possibile utilizzare tecniche asincrone per elaborare un bit che è stato letto, mentre sullo sfondo viene letto il bit successivo, ma penso che in questo caso si noterà un miglioramento minimo delle prestazioni.

Ho avuto un problema simile non molto tempo fa in un piccolo strumento in cui volevo calcolare le firme MD5 di tutti i file sul mio hard disk e ho scoperto che la CPU è troppo veloce rispetto al sistema di storage e io ha ottenuto risultati simili cercando di ottenere più prestazioni utilizzando più thread.

L'utilizzo della libreria parallela attività non ha alleviato questo problema.

+1

Sono d'accordo con quello che stai dicendo, ma non capisco perché se l'I/O del disco è il problema, posso elaborare i file più velocemente utilizzando più eseguibili su un singolo exe con più thread. Sento che probabilmente sto facendo qualcosa di sbagliato, ma non so cosa, dato che ogni thread opera in modo indipendente. – powlette

+0

Il tuo processo si accelera quando non fai nulla con ciò che leggi? Forse dovresti disabilitare questo e controllare il risultato. Immagino che parte del processo che stai facendo abbia problemi di blocco, anche se non puoi ancora vederlo. –

+0

Quanto più veloce è più veloce? Stiamo parlando di incrementi delle prestazioni a una o due cifre? –

2

Prima di tutto su un box 24 core se si utilizzano solo 4 thread la CPU più che potrebbe mai utilizzare è il 16,7%, quindi in realtà si ottiene il 60% di utilizzo, che è abbastanza buono.

È difficile stabilire se il programma è collegato I/O a questo punto, la mia ipotesi è che lo è. Devi eseguire un profiler sul tuo progetto e vedere quali sezioni di codice il tuo progetto sta spendendo al massimo il tempo. Se è seduto su un'operazione di lettura/scrittura è vincolato all'I/O.

È possibile che si utilizzi una forma di blocco interfilo. Ciò farebbe rallentare il programma man mano che si aggiungono altri thread, e sì, l'esecuzione di un secondo processo lo risolverebbe, ma risolverebbe anche il blocco.

Ciò a cui tutto si riduce è senza informazioni di profilazione, non possiamo dire se l'utilizzo di un secondo processo accelera le cose o rende le cose più lente, abbiamo bisogno di sapere se il programma è sospeso su un'operazione I/O, un blocco operazione, o semplicemente impiegando molto tempo in una funzione che può essere meglio parallelizzata.

+1

Questo è buono - sembra che il poster sia cattivo in matematica di primo livello, e anche il resto delle altre persone. Ecco la spiegazione: un thread viene eseguito solo su un core. Mai. Non è possibile lavorare su 2 core allo stesso tempo. Quindi con il 100% di utilizzo di 4 core .... di 24 .... il livello di utilizzo os 4/24 = 16.7 massimo (+ un po 'per il sistema operativo) comunque. Fisicamente impossibile ottenere di più. Vuoi il 100%? Passare a una macchina a 4 core. – TomTom

+0

@TomTom Come puoi leggere nella domanda, dopo i 4 thread l'applicazione effettivamente * perde * le prestazioni. Inoltre, nella mia macchina 4 Core, lo stesso comportamento si verifica quando inserisco più di 2 thread in qualche attività intensiva. È ovvio per me che un'applicazione ha un maximumun timeslice assegnato dal sistema operativo e tutti i suoi thread devono condividere questo timeslice. – ThunderGr

+0

@ThunderGr Ogni thread ha il proprio timelice, ovvero il punto di una discussione.Una macchina single core può eseguire un timeslice simultaneo, un core duo può eseguire due intervalli di tempo simultanei, ecc ... Il problema del poster è che la potenza di elaborazione della CPU non è un suo problema, il suo programma è in attesa sul disco per restituire IO o qualche risorsa che ha un blocco su di esso per essere liberato. L'aggiunta di più thread aumenta la scarsità di qualsiasi cosa il suo programma stia correndo e lo fa funzionare *** più lento *** –

0

Penso che si scopra quale cache di file non è l'ideale nel caso in cui uno proccess scrive i dati in molti file contemporaneamente. La cache dei file dovrebbe sincronizzarsi sul disco quando il numero di cache della pagina sporca supera una soglia. Sembra che gli autori concorrenti in una sola volta raggiungano una soglia di hit più veloce dello scrittore a thread singolo. È possibile leggere la lettura sulla cache del file system qui File Cache Performance and Tuning