Разделение хранилища данных параллельно, с частью хранилища данных на каждом работнике в параллельном пуле, может обеспечить преимущества во многих случаях:
Выполните некоторые действия только с одной частью всего хранилища данных или с несколькими определенными частями одновременно.
Поиск определенных значений в хранилище данных, при этом все работники одновременно работают на собственных секциях.
Выполните расчет сокращения для работников по всем разделам.
В этом примере показано, как использовать partition для параллелизма чтения данных из хранилища данных. Он использует небольшое хранилище данных авиакомпании, предоставленное в MATLAB ®, и находит среднее значение значений, не относящихся к NaN, из его'ArrDelay' столбец.
Простым способом вычисления среднего является деление суммы всех значений, не являющихся NaN, на число значений, не являющихся NaN. Следующий код делает это для хранилища данных сначала непараллельным способом. Для начала необходимо определить функцию для суммирования количества и суммы. Если требуется выполнить этот пример, скопируйте и сохраните эту функцию в папке на пути поиска команды MATLAB.
function [total,count] = sumAndCountArrivalDelay(ds) total = 0; count = 0; while hasdata(ds) data = read(ds); total = total + sum(data.ArrDelay,1,'OmitNaN'); count = count + sum(~isnan(data.ArrDelay)); end end
Следующий код создает хранилище данных, вызывает функцию и вычисляет среднее значение без параллельного выполнения. tic и toc используются для временного выполнения, здесь и в более поздних параллельных случаях.
ds = datastore(repmat({'airlinesmall.csv'},20,1),'TreatAsMissing','NA');
ds.SelectedVariableNames = 'ArrDelay';
reset(ds);
tic
[total,count] = sumAndCountArrivalDelay(ds)
sumtime = toc
mean = total/counttotal =
17211680
count =
2417320
sumtime =
7.7905
mean =
7.1201 partition функция позволяет разделить хранилище данных на более мелкие части, каждая из которых представлена в виде самого хранилища данных. Эти небольшие хранилища данных работают полностью независимо друг от друга, так что вы можете работать с ними внутри параллельных языковых функций, таких как parfor контуров и spmd блоки.
Количество разделов в следующем коде задается numpartitions функция, основанная на самом хранилище данных (ds) и параллельный пул (gcp) размер. Это не обязательно равно количеству работников в пуле. В этом случае количество итераций цикла устанавливается равным количеству секций (N).
Следующий код запускает параллельный пул в локальном кластере, затем секционирует хранилище данных среди работников для итерации по циклу. Опять же, вызывается отдельная функция, которая включает в себя parfor цикл для суммирования итогов подсчета и суммирования. Скопируйте и сохраните эту функцию, если требуется выполнить пример.
function [total, count] = parforSumAndCountArrivalDelay(ds) N = numpartitions(ds,gcp); total = 0; count = 0; parfor ii = 1:N % Get partition ii of the datastore. subds = partition(ds,N,ii); [localTotal,localCount] = sumAndCountArrivalDelay(subds); total = total + localTotal; count = count + localCount; end end
Теперь код MATLAB вызывает эту новую функцию, так что подсчет и суммирование значений, отличных от NAN, может происходить в параллельных итерациях цикла.
p = parpool('local',4);
reset(ds);
tic
[total,count] = parforSumAndCountArrivalDelay(ds)
parfortime = toc
mean = total/countStarting parallel pool (parpool) using the 'local' profile ...
Connected to the parallel pool (number of workers: 4).
total =
17211680
count =
2417320
parfortime =
6.4133
mean =
7.1201Вместо того, чтобы позволять программному обеспечению вычислять количество разделов, можно явно установить это значение, чтобы данные могли быть соответствующим образом разделены в соответствии с вашим алгоритмом. Например, для распараллеливания данных из spmd блок, можно указать количество работников (numlabs) как число используемых разделов. Следующая функция использует spmd блок для выполнения параллельного чтения и явно задает количество разделов, равное числу рабочих. Для выполнения этого примера скопируйте и сохраните функцию.
function [total,count] = spmdSumAndCountArrivalDelay(ds) spmd subds = partition(ds,numlabs,labindex); [total,count] = sumAndCountArrivalDelay(subds); end total = sum([total{:}]); count = sum([count{:}]); end
Теперь код MATLAB вызывает функцию, которая использует spmd блок.
reset(ds); tic [total,count] = spmdSumAndCountArrivalDelay(ds) spmdtime = toc mean = total/count
total =
17211680
count =
2417320
spmdtime =
4.6729
mean =
7.1201delete(p);
Parallel pool using the 'local' profile is shutting down.
Вы можете получить некоторое представление о скромных улучшениях производительности, сравнивая время, записанное в переменных sumtime, parfortime, и spmdtime. Результаты могут отличаться, поскольку на производительность могут влиять размер хранилища данных, размер параллельного пула, конфигурация оборудования и другие факторы.