2015-04-20 6 views
5

Ho implementato un algoritmo di ricerca combinatorio (per il confronto con una tecnica di ottimizzazione più efficiente) e ho cercato di migliorare il suo tempo di esecuzione con parfor.lavoro che ruba con Parallel Computing Toolbox

Sfortunatamente, gli incarichi di lavoro sembrano essere molto squilibrati.

Ogni sottotitolo i ha una complessità di circa nCr(N - i, 3). Come potete vedere, le attività i < N/4 implicano un lavoro significativamente più lungo di i > 3*N/4, ma sembra che MATLAB stia assegnando tutto il i < N/4 a un singolo lavoratore.

È vero che MATLAB divide il lavoro basato su sottoinsiemi di dimensioni uguali dell'intervallo di loop?

No, this question cita la documentazione dicendo che non è così.

C'è un modo conveniente per riequilibrare questo senza hardcoding il numero di lavoratori (ad esempio, se ho bisogno esattamente 4 lavoratori in piscina, quindi ho potuto scambiare i due bit più bassi di i con due punte più elevate al fine di garantire ogni lavoratore ha ricevuto un mix di compiti facili e difficili)?

Non credo che un pieno "work-rubare" implementazione è necessario, forse solo l'assegnazione 1, 2, 3, 4 ai lavoratori, poi, quando 4 completa prima, il suo operaio comincia su oggetto 5, e così via . La dimensione di ogni elemento è sufficientemente maggiore del numero di iterazioni che non sono troppo preoccupato per l'aumento del sovraccarico di comunicazione.

risposta

5

Se le iterazioni del ciclo sono effettivamente distribuite in anticipo (il che significherebbe che alla fine, c'è un singolo lavoratore che dovrà completare diverse iterazioni mentre gli altri lavoratori sono inattivi - è davvero così?), il modo più semplice per garantire un mix è quello di permutare in modo casuale le iterazioni del ciclo:

permutedIterations = randperm(nIterations); 
permutedResults = cell(nIterations,1); %# or whatever else you use for storing results 

%# run the parfor loop, completing iterations in permuted order 
parfor iIter = 1:nIterations 
    permutedResults(iIter) = f(permutedIterations(iIter)); 
end 

%# reorder results for easier subsequent analysis 
results = permutedResults(permutedIterations); 
+0

o forse con 'mod' invece di' randperm': supponendo 'nIterations' è un multiplo di' n Workers', utilizzare 'permutedIterations = rimodellare (rimodellare (1: nIterations, nWorkers, []) ', 1, [].) ' –