2010-07-04 8 views
17

il codice ho a che fare con i loop ha come le seguenti:MATLAB parfor è più lento di per - cosa c'è che non va?

bistar = zeros(numdims,numcases); 
parfor hh=1:nt  
    bistar = bistar + A(:,:,hh)*data(:,:,hh+1)' ; 
end 

per piccole nt (10).

Dopo averlo cronometrato, in realtà è 100 volte più lento rispetto al normale loop !!! So che Parfor può fare somme parallele, quindi non sono sicuro del perché questo non funzioni.

corro

matlabpool 

con le configurazioni out-of-the-box prima di eseguire il mio codice.

Sono relativamente nuovo in MATLAB e ho appena iniziato a utilizzare le funzionalità parallele, quindi per favore non presumere che non sto facendo qualcosa di stupido.

Grazie!

PS: Sto eseguendo il codice su un quad core, quindi mi aspetto di vedere alcuni miglioramenti.

+0

puoi dirci per favore i valori di numdims, numcases e le cifre temporali effettive che hai trovato? Grazie. – rwong

risposta

23

Il partizionamento e il raggruppamento dei risultati (sovraccarico nel dividere il lavoro e la raccolta dei risultati dai vari thread/core) è elevato per valori piccoli di nt. Questo è normale, non si partizionare i dati per attività facili che possono essere eseguite rapidamente in un ciclo semplice.

Eseguire sempre qualcosa di impegnativo all'interno del ciclo che merita il partizionamento. Ecco un bel introduction to parallel programming.

I thread provengono da un pool di thread in modo che l'overhead di creazione dei thread non dovrebbe essere lì. Ma per creare i risultati parziali, è necessario creare le matrici n dalla dimensione bistar, calcolare tutti i risultati parziali e quindi aggiungere tutti questi risultati parziali (ricombinazione). In un ciclo continuo, questo è con un'alta probabilità fatta sul posto, non avviene alcuna allocazione.

La dichiarazione completa nella guida (grazie per il tuo link di seguito) è:

Se il tempo di calcolare f, g, ed h è grande, parfor sarà significativamente più veloce rispetto al corrispondente per la dichiarazione , anche se n è relativamente piccola .

Quindi si vede che significano esattamente lo stesso di quello che intendo, il sovraccarico per piccoli valori n vale solo lo sforzo se ciò che si fa nel ciclo è complesso/richiede molto tempo.

+0

Grazie per la risposta, tuttavia in http://www.mathworks.com/access/helpdesk/help/toolbox/distcomp/parfor.html si afferma "parfor sarà significativamente più veloce dell'istruzione corrispondente, anche se n è relativamente piccolo." (Ofcourse idk cosa significa relativamente piccolo.) Sono confuso però, cosa intendi per overhead nel dividere il lavoro e raccogliere i risultati dai diversi thread/core? Le vars A e i dati sono globali e devono essere condivisi tra tutti i thread. Tutto ciò che MATLAB deve fare è essere con l'aggiunta al bisturi. – Junier

+0

Ho aggiunto una precisione, grazie per il collegamento Ho dato un'occhiata all'aiuto e afferma lo stesso di quello che cerco di chiarire. Non sono così bravo a spiegare la cosa :-) La parte "if" della frase è abbastanza importante. Spero che sia d'aiuto! Questo non è vero solo per MATLAB ma per tutti i tipi di calcolo parallelo. Partizionare adeguatamente il problema è essenziale. – jdehaan

+4

+1 per sottolineare la necessità di leggere tutto l'aiuto invece della sola parte che sembra dire quello che vuoi. – Donnie

13

Parfor viene fornito con un po 'di spese generali. Pertanto, se nt è veramente piccolo e se il calcolo nel ciclo viene eseguito molto rapidamente (come un'aggiunta), la soluzione parfor è più lenta. Inoltre, se si esegue parfor su un quad-core, il guadagno di velocità sarà vicino al lineare per 1-3 core, ma meno se si utilizzano 4 core, poiché anche l'ultimo core deve eseguire i processi di sistema.

Ad esempio, se il parfor viene fornito con 100ms di overhead e il calcolo nel ciclo richiede 5 ms e si assume che il guadagno di velocità sia lineare fino a 4 core con un coefficiente di 1 (ad es.utilizzando 4 core rende il calcolo 4 volte più veloce), nt deve essere di circa 30 per ottenere un guadagno di velocità con parfor (150 ms con for, 132 ms con parfor). Se dovessi eseguire solo 10 iterazioni, parfor sarebbe più lento (50 ms con for, 112 ms con parfor).

È possibile calcolare il sovraccarico sulla macchina confrontando i tempi di esecuzione con 1 lavoratore rispetto a 0 lavoratori e si può stimare il guadagno di velocità rendendo un rivestimento adatto ai tempi di esecuzione con da 1 a 4 lavoratori. Quindi saprai quando è utile usare parfor.

3

Oltre alle cattive prestazioni a causa del sovraccarico della comunicazione (vedere altre risposte), c'è un altro motivo per non utilizzare in questo caso lo parfor. Tutto ciò che viene fatto all'interno dello parfor in questo caso utilizza built-in multithreading. Supponendo che tutti i lavoratori siano in esecuzione sullo stesso PC, non vi è alcun vantaggio poiché una singola chiamata utilizza già tutti i core del processore.