In meiner persönlichen Erfahrung fand ich, dass parfeval
ist besser in Bezug auf Speicherverbrauch als parfor
. Darüber hinaus scheint Ihr Problem eher zerbrechlich zu sein. Sie können daher parfeval
verwenden, um kleinere Aufträge an MATLAB-Mitarbeiter zu senden.
Nehmen wir an, Sie haben workerCnt
MATLAB Worker, mit denen Sie arbeiten jobCnt
Jobs. Sei data
ein Zellenarray der Größe jobCnt x 1
, und jedes seiner Elemente entspricht einem Dateneingang für die Funktion getOutput
, die die Datenanalyse durchführt. Die Ergebnisse werden dann in dem Zellenfeld output
der Größe jobCnt x 1
gespeichert.
Im folgenden Code werden Jobs in der ersten for
-Schleife zugewiesen und die Ergebnisse werden in der zweiten while
-Schleife abgerufen. Die boolesche Variable doneJobs
gibt an, welcher Job ausgeführt wurde.
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
Auch Sie können diesen Ansatz einen Schritt weiter gehen, wenn Sie mehr Speicher sparen möchten. Sie können nach dem Abrufen der Ergebnisse eines abgeschlossenen Jobs das entsprechende Element future
löschen. Der Grund ist, dass dieses Objekt alle Eingabe- und Ausgabedaten der getOutput
-Funktion speichert, die wahrscheinlich sehr groß sein wird. Aber Sie müssen vorsichtig sein, wenn Mitglieder von future
Ergebnisse index shift löschen.
Das folgende ist der Code, den ich für diesen porpuse schrieb.
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
Wenn Ihre Daten ein [geschnitten Variable] ist (http://mathworks.com/help/distcomp/sliced-variables.html) es wird „geschnitten“ und diese Scheiben an die Arbeiter übertragen werden nur werden ; Verwenden Sie aufgeschnittene Variablen in Ihrem echten Code? –
Ich verwende ein Zellenfeld in meinem tatsächlichen Code, wie hier dargestellt. Ich werde in die geschnittene variable Funktion schauen, danke. – Adriaan
Vielleicht manuell schneiden, individuelle Jobs für jedes Stück einreichen: http://de.mathworks.com/help/distcomp/submit.html – Daniel