Ответ 1
В моем личном опыте я обнаружил, что использование parfeval
лучше относится к использованию памяти, чем parfor
. Кроме того, ваша проблема кажется более гибкой, поэтому вы можете использовать parfeval
для отправки более мелких заданий работникам MATLAB.
Скажем, что у вас есть работники workerCnt
MATLAB, с которыми вы собираетесь обрабатывать задания jobCnt
. Пусть data
- массив ячеек размером jobCnt x 1
, и каждый из его элементов соответствует вводу данных для функции getOutput
, которая выполняет анализ данных. Затем результаты сохраняются в массиве ячеек output
размера jobCnt x 1
.
в следующем коде, задания назначаются в первом цикле for
, и результаты извлекаются во втором цикле while
. Логическая переменная doneJobs
указывает, какое задание выполнено.
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
Кроме того, вы можете сделать этот подход еще на один шаг, если хотите сохранить больше памяти. Что вы можете сделать, так это то, что после получения результатов выполненного задания вы можете удалить соответствующий член future
. Причина в том, что этот объект хранит все входные и выходные данные функции getOutput
, которая, вероятно, будет огромной. Но вам нужно быть осторожным, поскольку удаление членов индекса future
изменяется.
Ниже приведен код, который я написал для этой породы.
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