2013-06-05 6 views
5

Ho creato questo test Matlab file di script:valori Vector differiscono se si accede dall'esterno o dall'interno di parfor

numbers = [29 37 44 54 62]; 

for i=1:length(numbers) 
    fprintf('%d\n', numbers(i)); 
end 

fprintf('***\n'); 

matlabpool local 5; 
parfor i=1:length(numbers) 
    fprintf('%d\n', numbers(i)); 
end % image loop 
fprintf('***\n') 
for i=1:length(numbers) 
    fprintf('%d\n', numbers(i)); 
end 
matlabpool close; 

fprintf('***\n'); 

for i=1:length(numbers) 
    fprintf('%d\n', numbers(i)); 
end 

quando l'eseguo, ottengo costantemente il seguente output:

29 
37 
44 
54 
62 
*** 
112 
111 
107 
117 
115 
*** 
29 
37 
44 
54 
62 
*** 
29 
37 
44 
54 
62 

Il fprintf all'interno del blocco parfor viene stampato il set apparentemente casuale di numeri che è, tuttavia, sempre lo stesso (112, 111, 107, 117, 115). Qualche idea sul perché questo sta accadendo?

UPDATE

È interessante notare che questo accade solo se corro lo script da riga di comando:

matlabR2012b -nodesktop -nosplash -nodisplay -r "run parfortest.m; exit" 

Se io prima aprire una sessione di Matlab e corro parfortest lì, allora i numeri sono stampati correttamente.

+0

Interessante - questo non mi succede. Che versione usi? – jazzbassrob

+0

A cosa serve il 'matlab pool'? Non mi sembra di avere una licenza per questo, ma dopo averlo rimosso ottengo gli stessi numeri (anche se in ordine inverso). – KronoS

+0

'matlabpool' apre un pool di worker per eseguire il codice parallelo, senza di esso,' parfor' è un semplice 'for'. – Oleg

risposta

2

Questo è specificamente un problema con l'esecuzione e non un problema di nodesktop. Per verificarlo, puoi provare

>> run parfortest.m 

dal desktop MATLAB e troverai lo stesso risultato.

Sebbene non sia una soluzione in quanto tale; se si omette di correre, e basta usare

>> parfortest 

l'uscita errata verrà corretta.

+0

Interessante. Questo potrebbe spiegare come il percorso viene passato a 'fprintf' o come' fprint' si confonda. – horchler

+0

Accetto, chiamare dalla finestra di cmd 'esegui parfortest' produce il problema e senza' run' no. Pertanto, non è dovuto all'esecuzione della riga di comando. – Oleg

+1

Stranamente, se chiamo 'evalin ('caller', [script ';'])' dalla finestra di comando come in 'run' non sono in grado di replicare il problema - anche se sono nella stessa directory del M-file. Cos'altro sta succedendo? Il '' caller'' della finestra di comando non dovrebbe essere equivalente a quello di 'run'? Cambiare lo spazio di lavoro in "base" non fa differenza. – horchler

0

Immagino che non si possa realmente scrivere in parallelo un file. O in questo caso la schermata di output poiché fprintf ("testo") implica fprintf (1, "testo") dove 1 è il fileID per la schermata di output.

Il file viene ora modificato da più processi, il che rappresenta un problema poiché il buffer utilizzato non viene svuotato prima dell'inizio di altre operazioni e il comportamento sarà errato.

Forse il collegamento this aiuterà.

1

Posso anche replicarlo su OS X, R2012b. In mex, mexPrintf non è thread safe. Vedi this. Non sarei sorpreso se Matlab's fprintf si basi su mexPrintf - o codice simile - sotto il cofano. Se trasformi il tuo script in una funzione - metti semplicemente function parfortest sulla prima riga - il problema scompare, quindi potrebbe anche essere un problema di ambito.

MODIFICA: provare a stampare più di cinque numeri, diciamo dodici. Ora utilizzare char per convertire questi valori in caratteri ASCII. Sembra che, nel ciclo parforfprintf stia stampando il percorso del file eseguito tramite il comando Terminale (qualche forma di parfortest.m in ordine casuale - Ho eseguito il file da ~/Desktop/parfortest.m e convertendo il numero da fprintf in caratteri che ho ottenuto D/~ksepotap/frroetst.m). Se provi a stampare più valori rispetto alla lunghezza del percorso, otterrai un errore. Non riesco a trovare una soluzione alternativa oltre a trasformare il tuo script in una funzione (che comunque è una buona idea). Sicuramente sembra un insetto.