Nella mia esperienza personale, ho trovato che usare parfeval
è meglio per quanto riguarda l'utilizzo della memoria di parfor
. Inoltre, il tuo problema sembra essere più fragile, quindi puoi usare parfeval
per inviare lavori più piccoli ai lavoratori di MATLAB.
Supponiamo che tu abbia workerCnt
lavoratori MATLAB a cui gestirai i lavori jobCnt
. Sia data
un array di celle di dimensioni jobCnt x 1
e ognuno dei suoi elementi corrisponde a un input di dati per la funzione getOutput
che esegue l'analisi sui dati. I risultati vengono quindi memorizzati nell'array di celle output
della dimensione jobCnt x 1
.
nel seguente codice, i lavori vengono assegnati nel primo ciclo for
ei risultati vengono recuperati nel secondo ciclo while
. La variabile booleana doneJobs
indica quale lavoro è stato eseguito.
poolObj = parpool(workerCnt);
jobCnt = length(data); % number of jobs
output = cell(jobCnt,1);
for jobNo = 1:jobCnt
future(jobNo) = parfeval(poolObj,@getOutput,...
nargout('getOutput'),data{jobNo});
end
doneJobs = false(jobCnt,1);
while ~all(doneJobs)
[idx,result] = fetchnext(future);
output{idx} = result;
doneJobs(idx) = true;
end
Inoltre, è possibile adottare questo approccio un ulteriore passo avanti se si desidera risparmiare più memoria. Quello che potresti fare è che dopo aver recuperato i risultati di un lavoro svolto, puoi eliminare il membro corrispondente di future
. Il motivo è che questo oggetto memorizza tutti i dati di input e output della funzione getOutput
che probabilmente sarà enorme. Ma devi stare attento, eliminando i membri dello spostamento dell'indice dei risultati future
.
Quanto segue è il codice che ho scritto per questo porpuse.
poolObj = parpool(workerCnt);
jobCnt = length(data); % number of jobs
output = cell(jobCnt,1);
for jobNo = 1:jobCnt
future(jobNo) = parfeval(poolObj,@getOutput,...
nargout('getOutput'),data{jobNo});
end
doneJobs = false(jobCnt,1);
while ~all(doneJobs)
[idx,result] = fetchnext(future);
furure(idx) = []; % remove the done future object
oldIdx = 0;
% find the index offset and correct index accordingly
while oldIdx ~= idx
doneJobsInIdxRange = sum(doneJobs((oldIdx + 1):idx));
oldIdx = idx
idx = idx + doneJobsInIdxRange;
end
output{idx} = result;
doneJobs(idx) = true;
end
Se i dati sono un [variabile a fette] (http://mathworks.com/help/distcomp/sliced-variables.html) sarà "fette" e solo quelle fette verranno trasmesse ai lavoratori ; stai usando le variabili affettate nel tuo codice reale? –
Sto usando un array di celle nel mio codice attuale, come presentato qui. Vedrò la funzione variabile a fette, grazie. – Adriaan
Forse si affetta manualmente, inviando singoli lavori per ogni pezzo: http://de.mathworks.com/help/distcomp/submit.html – Daniel