2010-06-21 16 views
5

Ci scusiamo per la vaga domanda sull'argomento, ma sto lavorando su alcune routine di elaborazione video accademiche. Gli algoritmi sono scritti in MATLAB e, sebbene sia adatto per scopi di sviluppo, ha elaborato un video a circa 60spf o circa .0166fps. Inutile dire che questo non sarà sufficiente per le demo e così via, quindi il mio lavoro estivo è convertire la routine in qualcosa che verrà eseguito drasticamente più veloce.Qual è la soluzione migliore per un problema parallelo imbarazzante?

Ho riscritto la parte più lenta del codice per CUDA, la soluzione GPGPU di nvidia. Tuttavia, c'è anche una gran parte del codice che sembra essere meglio fatto sulla CPU, in quanto è relativamente seriale. Il problema è che la macchina che mi è stata data ha 2 processori Xeon, con 8 core logici totali, e sembra essere un peccato strozzare il codice GPU codificando solo per single core. Il processo di conversione video è funzionale in quanto ogni frame non dipende da altri frame, quindi pensavo che una sorta di coda/flusso asincrono sarebbe stata la soluzione migliore.

Qui giace la mia domanda: quale sarebbe il modo migliore per ottenere questo tipo di parallelismo con il miglior rapporto tra sforzo e resa di velocità?

Alcune delle soluzioni che ho visto sono OpenMP, .net TPL e solo semplici pthreads.

Ho solo un'esposizione di base alla programmazione asincrona, quindi preferirei usare una libreria o qualcosa del genere piuttosto che andare in giro con mutex e barriere e spararmi al piede più volte. Non mi dispiace apprendere, perché questo è uno dei miei obiettivi per questa estate, ma allo stesso tempo, il parallelismo è rigido. Tuttavia, se la differenza di velocità è in realtà molto evidente, sono disposto a strapparmi i capelli per un paio di settimane. : P

Grazie in anticipo.

+0

Se è possibile suddividere il problema in più parti su cui è possibile lavorare senza interferenze (con punti di sincronizzazione ben definiti), la "libreria" utilizzata dovrebbe essere solo zucchero ... un modo semplice è solo utilizzare un pool di thread, code simultanee (una per l'input, una per l'output) e solo l'accesso agli oggetti/dati che il thread "possiede" (questo può essere ingrandito a strutture esterne immutabili). –

risposta

3

Se massimizzare lo sforzo di rendimento è il tuo obiettivo, ti consiglio di consultare TPL in .NET. Questo è probabilmente il modo più semplice per implementarlo. A seconda di cosa sta facendo il tuo codice, potresti creare una pipeline o anche solo usare Parallel.For (o ForEach) su ogni "frame".

Detto questo, se si desidera attenersi al codice nativo non gestito, una buona opzione potrebbe essere il nuovo Parallel Patterns Library o Intel's Threading Building Blocks di Microsoft. Entrambi hanno costrutti simili al nuovo TPL, specialmente per il parallelismo dei dati, e renderebbero abbastanza semplice la parallelizzazione, a condizione che "ogni frame non dipenda da altri frame" rimanga vero.

+0

Picchiami! Ade Miller ha parlato bene con TechEd sulle opzioni di parallelismo disponibili con .Net 4.0: http://www.msteched.com/2010/NorthAmerica/ARC205 – Mathias

+0

PPL sembra proprio come quello che stavo cercando, grazie. Una domanda, però, utilizza codice gestito come il codice di rallentamento C# come il mio in modo evidente, dove è principalmente aritmetica in virgola mobile su grandi matrici? Mi piace l'ambiente di programmazione molto semplificato, ma con cose come l'elaborazione video, sono sempre titubante a causa dei timori di garbage collection e controllo del sovraccarico. Potrebbe essere solo la vecchia paranoia della programmazione in C: \ – Xzhsh

+0

Xzhsh: Io personalmente uso C# e codice gestito per l'elaborazione dei dati scientifici nel mio "lavoro di un giorno". Lo fa molto bene, ma il perf. le caratteristiche sono diverse dal codice nativo - quindi devi adattare il tuo pensiero per compensare. Personalmente non mi preoccuperei del fatto che il GC sia un problema, ma il controllo dei limiti dell'array può rallentare (questo può essere disabilitato). Nella maggior parte dei casi, però, un'accurata profilazione e un codice gestito "buono" possono portare a un codice altrettanto veloce (e spesso più veloce) del codice nativo. –

1

Il mio consiglio sarebbe quello di affrontare questo in un modo passo-passo.

  1. Prima di tutto, dimostrare di avere un'implementazione funzionale non MATLAB. Questo non è banale e, francamente, penso che dovresti pianificare di spendere il 100% dei tuoi cicli cerebrali per ottenere la correttezza prima di pensare alle prestazioni.

  2. Partizione la tua soluzione: prova che puoi prendere la routine che pensi sia disgiunta dal resto dell'implementazione e isolarla sintatticamente dal resto del codice. Ad esempio, se si parla di un ray tracer, si potrebbe prendere la matematica che risulta da un singolo punto di vista che spara un raggio attraverso un singolo pixel nell'ambiente comune. Anche questo non è banale in quanto richiede di pensare a ciò che è in realtà comune (ad esempio, la geometria dell'ambiente, le mappe di texture, ecc.) E ciò che è specifico di una situazione unica (ad esempio, ray da occhio a pixel) . Il profilo delle prestazioni è tuo amico qui.

  3. Identificare la sintassi delle librerie o dei framework a cui si è interessati che saranno necessari per creare thread/processi in parallelo, avviarli e unire i risultati dopo il completamento. Nota: è necessario avere l'esclusione reciproca su dati condivisi, ecc. Ad esempio, nel mondo Java, questo sarebbe java.util.concurrency.

  4. Provare a creare due (solo due) thread per partizionare il lavoro a metà. Scrivi benchmark che ti consentano di misurare la tua soluzione iniziale, la soluzione per N = 2 thread e profilare i risultati.

  5. Solo allora si dovrebbe anche pensare a un'ulteriore parallelizzazione.

Se si seguono passaggi come questi, si (a) riuscire a vostro compito attuale (porto da MATLAB), (b) avere qualcosa che funziona per alcune metriche di performance noti e (c) avere una chiara percorso futuro se desideri sfruttare ulteriormente le opportunità di parallelizzazione.

+0

Grazie per il suggerimento Bob! Ho già eseguito il porting delle routine su prevalentemente C, e il parallelismo sarebbe stato solo tra i frame che sono completamente indipendenti. Mi piace il tuo consiglio, e sicuramente lo terrò a mente per il mio prossimo progetto – Xzhsh

+0

@Xzhsh, FYI, nella mia grafica personale il miglior parallelismo era in realtà per fotogramma piuttosto che assegnare un intero fotogramma indipendentemente ai singoli processori . L'ambiente condiviso fortemente motivato partizionare i pixel ai vari thread e accelerare il calcolo di un singolo fotogramma (era un raytracer dopo tutto). La scelta degli approcci è probabilmente un altro buon argomento per te da investigare come parte del tuo progetto. –

Problemi correlati