По своему личному опыту я обнаружил, что использование 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
приводит к смещению индекса.
Ниже приведен код, который я написал для этого 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
person
milaniez
schedule
04.09.2015
gather
после циклаparfor
здесь является избыточным —gather
используется для преобразования массиваdistributed
в обычный массив MATLAB. - person Edric   schedule 20.08.2015Mx7
сM
порядка сотен миллионов, и я разбиваю его на восемь частей (мое количество ядер), а затем сохраняю каждую часть в ячейке, как показано. - person Adriaan   schedule 01.09.2015